58 lines
No EOL
1.6 KiB
Python
58 lines
No EOL
1.6 KiB
Python
def main():
|
|
with open("input.txt") as f:
|
|
lines = f.read().split('\n')
|
|
foods = [s[:-1].split(' (contains ') for s in lines]
|
|
# map allergens to possible ingredients
|
|
possible = [
|
|
(allergen, set(food[0].split(' ')))
|
|
for food in foods
|
|
for allergen in food[1].split(', ')
|
|
]
|
|
# get sets of all allergens and all ingredients
|
|
allergens = {p[0] for p in possible}
|
|
ingredients = set.union(*[p[1] for p in possible])
|
|
# find which ingredients are always listed for a given allergen
|
|
possible = {
|
|
a:set.intersection(*[
|
|
s[1]
|
|
for s in possible
|
|
if s[0] == a]
|
|
) for a in allergens
|
|
}
|
|
# reduce
|
|
while any({i for i in possible if len(possible[i]) > 1}):
|
|
for b in {j for j in possible if len(possible[j]) > 1}:
|
|
for a in {i for i in possible if len(possible[i]) == 1}:
|
|
possible[b] -= possible[a]
|
|
# find sets of allergenic and non-allergenic
|
|
unsafe = set.union(*list(possible.values()))
|
|
safe = ingredients - unsafe
|
|
#
|
|
print('|non-allergen occurrences| =', sum(
|
|
food[0].split().count(s)
|
|
for food in foods
|
|
for s in safe)
|
|
)
|
|
print('allergens:', ','.join(
|
|
[
|
|
list(possible[a])[0]
|
|
for a in sorted(list(possible))
|
|
])
|
|
)
|
|
|
|
"""
|
|
all_ingredients = set()
|
|
all_allergens = set()
|
|
may_contain = {}
|
|
unsafe_ingredients = {}
|
|
foods = []
|
|
for line in lines:
|
|
ingredients, contains = line.split(' (contains ')
|
|
ingredients = ingredients.split(' ')
|
|
contains = contains[:-1].split(', ') # remove trailing ")" then split
|
|
all_ingredients = all_ingredients | set(ingredients)
|
|
all_allergens = all_allergens | set(contains)
|
|
"""
|
|
|
|
if __name__ == "__main__":
|
|
main() |