21.py 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. from itertools import product
  2. lines = []
  3. with open("21.input") as f:
  4. for line in f.readlines():
  5. lines.append(line.strip())
  6. pairs = []
  7. all_allergens = set()
  8. all_ingredients = set()
  9. for line in lines:
  10. [ingredients, allergens] = line.split(" (contains ")
  11. allergens = allergens[:-1] # Remove last parentheses
  12. allergens = allergens.split(", ")
  13. ingredients = ingredients.split(" ")
  14. all_allergens = all_allergens.union(set(allergens))
  15. all_ingredients = all_ingredients.union(set(ingredients))
  16. pairs.append((ingredients, allergens))
  17. # Returns True if a implies b
  18. def impl(a, b):
  19. if not a:
  20. return True
  21. else:
  22. return b
  23. possible_combinations = [(a, i) for (a, i) in product(all_allergens, all_ingredients) if all([impl(a in als, i in ins) for (ins, als) in pairs])]
  24. possible_options = {}
  25. for (a, i) in possible_combinations:
  26. l = possible_options.get(a, [])
  27. l.append(i)
  28. possible_options[a] = l
  29. unsafe_ingredients = [i for (a, i) in possible_combinations]
  30. safe_ingredients = [i for i in all_ingredients if i not in unsafe_ingredients]
  31. print("Answer 1:", len([i for (ins, als) in pairs for i in ins if i not in unsafe_ingredients]))
  32. danger_list = []
  33. while len(possible_options) > 0:
  34. for (k, v) in possible_options.items():
  35. if len(v) == 1:
  36. ingredient = v[0]
  37. danger_list.append((k, ingredient))
  38. for (k2, v2) in possible_options.items():
  39. if ingredient in v2:
  40. v2.remove(ingredient)
  41. del possible_options[k]
  42. break
  43. danger_list.sort()
  44. print("Answer 2:", ",".join([b for (a, b) in danger_list]))