advent-of-code/2020/day21/day21.py

34 lines
1.3 KiB
Python
Executable file

#!/usr/bin/env python
import sys
def parse_line(line):
ingredients, allergens = line.split('(contains ')
return (set(ingredients.strip().split(' ')), set(allergens.strip().strip(')').split(', ')))
def reduce(allergen_name_candidates):
name, allergen = next((list(names)[0], allergen) for allergen, names in allergen_name_candidates.items() if len(names) == 1)
for names in allergen_name_candidates.values():
names.discard(name)
del allergen_name_candidates[allergen]
return name, allergen
if __name__ == '__main__':
lines = [parse_line(line) for line in sys.stdin.readlines()]
allergens = set.union(*(allergens for _, allergens in lines))
allergen_name_candidates = {}
for allergen in allergens:
allergen_name_candidates[allergen] = set.intersection(*(ingredients for ingredients, allergens in lines if allergen in allergens))
allergen_names = {}
while allergen_name_candidates:
name, allergen = reduce(allergen_name_candidates)
assert name not in allergen_names
allergen_names[name] = allergen
total = sum(len(ingredients - set(allergen_names)) for ingredients, _ in lines)
print(total)
names = ','.join(name for name, _ in sorted(list(allergen_names.items()), key=lambda x: x[1]))
print(names)