|
| 1 | +from assertions import assert_equals |
| 2 | +from input_reader import read_lines |
| 3 | +from printer import aoc_print |
| 4 | + |
| 5 | + |
| 6 | +def contains_bag(root: str, needle: str) -> bool: |
| 7 | + ignore_counts = map(lambda x: x[0], bag_rules[root]) |
| 8 | + |
| 9 | + if needle in ignore_counts: |
| 10 | + return True |
| 11 | + else: |
| 12 | + for bag in bag_rules[root]: |
| 13 | + if contains_bag(bag[0], needle): |
| 14 | + return True |
| 15 | + |
| 16 | + return False |
| 17 | + |
| 18 | + |
| 19 | +def count_bags(root: str) -> int: |
| 20 | + total_sum = 0 |
| 21 | + for rule in bag_rules[root]: |
| 22 | + total_sum += rule[1] + rule[1] * count_bags(rule[0]) |
| 23 | + |
| 24 | + return total_sum |
| 25 | + |
| 26 | + |
| 27 | +# Parse input (plz forgive me python god and regex skiller) |
| 28 | +rule_list = read_lines("day07") |
| 29 | + |
| 30 | +# {str, [(int,str)]} |
| 31 | +bag_rules = {} |
| 32 | + |
| 33 | +for rule in rule_list: |
| 34 | + rule = rule[:-1].replace("bags", "").replace("bag", "") |
| 35 | + |
| 36 | + bag = rule.split(" contain ")[0].strip() |
| 37 | + container_bags = [] |
| 38 | + |
| 39 | + container = rule.split(" contain ")[1].strip() |
| 40 | + if "," in container: |
| 41 | + for single_bag in container.split(", "): |
| 42 | + count = int(single_bag.split(" ")[0]) |
| 43 | + bag_type = single_bag[len(single_bag.split(" ")[0]):].strip() |
| 44 | + container_bags.append((bag_type, count)) |
| 45 | + elif "no " not in container: |
| 46 | + count = int(container.split(" ")[0]) |
| 47 | + bag_type = container[len(rule.split(" contain ")[1].strip().split(" ")[0]):].strip() |
| 48 | + container_bags.append((bag_type, count)) |
| 49 | + |
| 50 | + bag_rules[bag] = container_bags |
| 51 | + |
| 52 | +# Part one |
| 53 | +res = len([bag for bag in bag_rules.keys() if contains_bag(bag, "shiny gold")]) |
| 54 | + |
| 55 | +aoc_print(f"{res} bag colors can contain at least one shiny gold.") |
| 56 | +assert_equals(302, res) |
| 57 | + |
| 58 | +# Part two |
| 59 | +res = count_bags("shiny gold") |
| 60 | + |
| 61 | +aoc_print(f"It requires {res} bags in my shiny gold bag.") |
| 62 | +assert_equals(4165, res) |
0 commit comments