35 lines
1.3 KiB
Python
35 lines
1.3 KiB
Python
|
#!/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)
|