diff --git a/2020/21/21.py b/2020/21/21.py index 2bb3fc6..c08e4bf 100644 --- a/2020/21/21.py +++ b/2020/21/21.py @@ -1,16 +1,58 @@ def main(): - with open("input_sample.txt") as f: + 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() \ No newline at end of file