Last active
April 14, 2021 18:34
-
-
Save sanandrea/df3e696a0d9b908d391a9f3decfc870e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from functools import reduce | |
in_file = open('/users/andi/xworkspace/AdventOfCode-2020/input_21') | |
file_lines = in_file.readlines() | |
class Food: | |
def __init__(self, input_str): | |
all_tokens = input_str.strip().split('contains') | |
self.allergens = [a.strip() for a in all_tokens[1][:-1].split(',')] | |
self.ingredients = [a.strip() for a in all_tokens[0][:-2].split(' ')] | |
allergen_to_foods_map = {} | |
all_food_list = [] | |
for line in file_lines: | |
f = Food(line) | |
all_food_list.append(f) | |
for allergen in f.allergens: | |
if allergen not in allergen_to_foods_map: | |
allergen_to_foods_map[allergen] = [f] | |
else: | |
allergen_to_foods_map[allergen].append(f) | |
ingredients_containing_allergens_set = set() | |
allergens_to_ingredients_map = {} | |
for allergen in allergen_to_foods_map: | |
# list of lists of ingredients that this allergen appears | |
all_lists_of_ingredients = list(map(lambda f: f.ingredients, allergen_to_foods_map[allergen])) | |
ingredients_that_might_contain_allergen = list(reduce(lambda a, b: set(a) & set(b), all_lists_of_ingredients)) | |
ingredients_containing_allergens_set.update(ingredients_that_might_contain_allergen) | |
allergens_to_ingredients_map[allergen] = ingredients_that_might_contain_allergen | |
safe_ingredients = [] | |
for food in all_food_list: | |
safe_ingredients.extend(set(food.ingredients) - ingredients_containing_allergens_set) | |
print('Part 1: ', len(safe_ingredients)) | |
allergen_ingredient_map = {} | |
while allergens_to_ingredients_map: | |
for allergen in list(allergens_to_ingredients_map.keys()): | |
if len(allergens_to_ingredients_map[allergen]) == 1: | |
allergen_ingredient_map[allergen] = allergens_to_ingredients_map[allergen][0] | |
ingredient = allergens_to_ingredients_map.pop(allergen)[0] | |
for other_allergen in allergens_to_ingredients_map: | |
if ingredient in allergens_to_ingredients_map[other_allergen]: allergens_to_ingredients_map[other_allergen].remove(ingredient) | |
canonical_dangerous_ingredient_list = [] | |
for key in sorted(allergen_ingredient_map): | |
canonical_dangerous_ingredient_list.append(allergen_ingredient_map[key]) | |
print('Part 2: ', ','.join(canonical_dangerous_ingredient_list)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment