aoc/2020/21/21.py

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()