|
- import re
- import sys
-
-
- def words(string):
- return frozenset(re.findall(r'\w+', string))
-
-
- text = sys.stdin.read()
- recipes = dict(map(words, ln.split('contains')) for ln in text.splitlines())
- all_ingredients = {item for group in recipes.keys() for item in group}
- all_allergens = {item for group in recipes.values() for item in group}
-
- # any ingredient can be any allergen,
- # but if the allergen *is* there, and the ingredient *isn't*
- # then the ingredient *cannot* be the allergen
- options = {ingredient: set(all_allergens) for ingredient in all_ingredients}
- for ingredients, allergens in recipes.items():
- for f2 in all_ingredients - ingredients:
- options[f2] -= allergens
-
- clean = {ing for ing, als in options.items() if not als}
- ans = sum(len(recipe & clean) for recipe in recipes)
- print(ans)
-
-
- def recurse(leftover, known=[]):
- if not leftover:
- yield dict(known)
- else:
- ing, = key = min(leftover, key=len)
- for alg in leftover.pop(key):
- a1 = {k - {ing}: v - {alg} for k, v in leftover.items()}
- a2 = known + [(ing, alg)]
- yield from recurse(a1, a2)
-
-
- def valid(mapping):
- return all(mapping[a] in fs for fs, als in recipes.items() for a in als)
-
-
- cleaned_up = {v: k - clean for k, v in recipes.items()}
- maps, = (maps for maps in recurse(cleaned_up) if valid(maps))
- print(','.join(v for k, v in sorted(maps.items())))
|