|
|
|
#!/usr/bin/env python
|
|
|
|
|
|
|
|
from aoc import get_input # AoC
|
|
|
|
import re # regex
|
|
|
|
from collections import defaultdict as dd
|
|
|
|
from copy import deepcopy as copy
|
|
|
|
|
|
|
|
data = get_input(21).splitlines()
|
|
|
|
|
|
|
|
foodlist = []
|
|
|
|
allfood = []
|
|
|
|
|
|
|
|
allerlist = []
|
|
|
|
|
|
|
|
allerthing = dd(set)
|
|
|
|
|
|
|
|
for food in data:
|
|
|
|
cont, aller = food.split("(")
|
|
|
|
cont = cont.strip().split(" ")
|
|
|
|
aller = aller.replace(")", "").replace("contains ", "").split(", ")
|
|
|
|
|
|
|
|
foodlist.append(cont)
|
|
|
|
allerlist.append(set(aller))
|
|
|
|
|
|
|
|
for c in cont:
|
|
|
|
allfood.append(c)
|
|
|
|
|
|
|
|
|
|
|
|
for i, food in enumerate(foodlist):
|
|
|
|
aller = allerlist[i]
|
|
|
|
|
|
|
|
for al in aller:
|
|
|
|
if( not al in allerthing.keys() ):
|
|
|
|
allerthing[al] = set(food)
|
|
|
|
else:
|
|
|
|
allerthing[al] &= set(food)
|
|
|
|
|
|
|
|
#print(allerthing)
|
|
|
|
|
|
|
|
for aller, cont in allerthing.items():
|
|
|
|
for thing in cont:
|
|
|
|
while(thing in allfood):
|
|
|
|
allfood.remove(thing)
|
|
|
|
|
|
|
|
print(len(allfood))
|
|
|
|
|
|
|
|
ignorefoods = set( [food for food in allfood] )
|
|
|
|
|
|
|
|
seenaller = set()
|
|
|
|
seenfood = set()
|
|
|
|
|
|
|
|
thing = dd(set)
|
|
|
|
|
|
|
|
def getFood(foodList, exclude=set()):
|
|
|
|
food = set(foodList)
|
|
|
|
for ignore in ignorefoods:
|
|
|
|
food.discard(ignore)
|
|
|
|
|
|
|
|
for ex in exclude:
|
|
|
|
food.discard(exclude)
|
|
|
|
|
|
|
|
return food
|
|
|
|
|
|
|
|
takenAllers = set()
|
|
|
|
for i, food in enumerate(foodlist):
|
|
|
|
food = getFood(food)
|
|
|
|
aller = allerlist[i]
|
|
|
|
|
|
|
|
if( len(food) == 1 and len(aller) == 1 ):
|
|
|
|
if( not list(aller)[0] in takenAllers ):
|
|
|
|
thing[list(food)[0]] = list(aller)[0]
|
|
|
|
ignorefoods.add(list(food)[0])
|
|
|
|
|
|
|
|
elif(len(food) > 1 and len(aller) > 1):
|
|
|
|
for j, food2 in enumerate(foodlist):
|
|
|
|
if(i == j):
|
|
|
|
continue
|
|
|
|
|
|
|
|
food2 = getFood(food2)
|
|
|
|
aller2 = allerlist[j]
|
|
|
|
|
|
|
|
commonFood = list(food & food2)
|
|
|
|
commonAller = list(set(aller) & set(aller2))
|
|
|
|
|
|
|
|
for ignore in ignorefoods:
|
|
|
|
while(ignore in commonFood):
|
|
|
|
commonFood.remove(ignore)
|
|
|
|
|
|
|
|
for ignore in takenAllers:
|
|
|
|
while(ignore in commonAller):
|
|
|
|
commonAller.remove(ignore)
|
|
|
|
|
|
|
|
print(commonFood, commonAller)
|
|
|
|
|
|
|
|
if(len(commonFood) >= 1 and len(commonAller) >= 1):
|
|
|
|
if( not commonAller[0] in takenAllers ):
|
|
|
|
thing[commonFood[0]] = commonAller[0]
|
|
|
|
ignorefoods.add(commonFood[0])
|
|
|
|
takenAllers.add(commonAller[0])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print(thing)
|
|
|
|
sortedthing = sorted(thing.items(), key = lambda kv:(kv[1], kv[0]))
|
|
|
|
print(sortedthing)
|
|
|
|
|
|
|
|
part2 = ""
|
|
|
|
for i, sort in enumerate(sortedthing):
|
|
|
|
part2 += f"{sort[0]}"
|
|
|
|
if( i < len(sortedthing)-1 ):
|
|
|
|
part2 += ","
|
|
|
|
|
|
|
|
print("###########", part2)
|