123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657 |
- from itertools import product
- lines = []
- with open("21.input") as f:
- for line in f.readlines():
- lines.append(line.strip())
- pairs = []
- all_allergens = set()
- all_ingredients = set()
- for line in lines:
- [ingredients, allergens] = line.split(" (contains ")
- allergens = allergens[:-1] # Remove last parentheses
- allergens = allergens.split(", ")
- ingredients = ingredients.split(" ")
- all_allergens = all_allergens.union(set(allergens))
- all_ingredients = all_ingredients.union(set(ingredients))
- pairs.append((ingredients, allergens))
- # Returns True if a implies b
- def impl(a, b):
- if not a:
- return True
- else:
- return b
- possible_combinations = [(a, i) for (a, i) in product(all_allergens, all_ingredients) if all([impl(a in als, i in ins) for (ins, als) in pairs])]
- possible_options = {}
- for (a, i) in possible_combinations:
- l = possible_options.get(a, [])
- l.append(i)
- possible_options[a] = l
- unsafe_ingredients = [i for (a, i) in possible_combinations]
- safe_ingredients = [i for i in all_ingredients if i not in unsafe_ingredients]
- print("Answer 1:", len([i for (ins, als) in pairs for i in ins if i not in unsafe_ingredients]))
- danger_list = []
- while len(possible_options) > 0:
- for (k, v) in possible_options.items():
- if len(v) == 1:
- ingredient = v[0]
- danger_list.append((k, ingredient))
- for (k2, v2) in possible_options.items():
- if ingredient in v2:
- v2.remove(ingredient)
- del possible_options[k]
- break
- danger_list.sort()
- print("Answer 2:", ",".join([b for (a, b) in danger_list]))
|