import collections def read_food(): with open('day21/input') as reader: return reader.readlines() food_as_text = read_food() food = [] for f in food_as_text: ingredients, allergens = f[:-1].split(' (contains ') food.append((ingredients.split(' '), allergens[:-1].split(', '))) def get_allergen_possibilities(food): allergen_possibilities = {} for ingredients, allergens in food: for a in allergens: if a not in allergen_possibilities.keys(): allergen_possibilities[a] = set(ingredients) else: allergen_possibilities[a] = allergen_possibilities[a].intersection(set(ingredients)) return allergen_possibilities def get_all_ingredients_with_possible(allergen_possibilities): all_ingredients_with_possible = set() for i in allergen_possibilities.values(): all_ingredients_with_possible = all_ingredients_with_possible.union(i) return all_ingredients_with_possible def get_all_ingredients(food): all_ingredients = set() for ingredients, allergens in food: all_ingredients = all_ingredients.union(ingredients) return all_ingredients def count_no_allergens(food, no_allergen): c = 0 for ingredients, allergens in food: for i in ingredients: if i in no_allergen: c += 1 return c def find_allergens(allergen_possibilities): defined_allergens = {} while True: found_key, found_value = next((key, value) for key, value in allergen_possibilities.items() if len(value) == 1) ingredient_defined = list(found_value)[0] defined_allergens[found_key] = ingredient_defined del allergen_possibilities[found_key] for allergen in allergen_possibilities.keys(): if ingredient_defined in allergen_possibilities[allergen]: allergen_possibilities[allergen].remove(ingredient_defined) if not allergen_possibilities: break return defined_allergens allergen_possibilities = get_allergen_possibilities(food) all_ingredients_with_possible = get_all_ingredients_with_possible(allergen_possibilities) all_ingredients = get_all_ingredients(food) no_allergen = all_ingredients.difference(all_ingredients_with_possible) res = count_no_allergens(food, no_allergen) print(res) defined_allergens = find_allergens(allergen_possibilities) ordered_by_insertion = collections.OrderedDict(sorted(defined_allergens.items())) canonical_dangerous_ingredient_list = ','.join([v for v in ordered_by_insertion.values()]) print(canonical_dangerous_ingredient_list)