82 lines
2.1 KiB
Python
82 lines
2.1 KiB
Python
from aoc.input import get_input
|
|
import copy
|
|
import itertools
|
|
import time
|
|
import collections
|
|
import re
|
|
from aoc.partselector import part_one, part_two
|
|
import functools
|
|
|
|
def pw(line):
|
|
return line.strip()
|
|
|
|
def p1():
|
|
inp = get_input(pw)
|
|
lst = []
|
|
ingredients = set()
|
|
lingredients = []
|
|
idict = collections.defaultdict(list)
|
|
for sample in inp:
|
|
i, a = sample.split('(contains ')
|
|
a = a[:-1].strip()
|
|
lst.append((i.strip().split(' '), a.split(', ')))
|
|
is_ = i.strip().split(' ')
|
|
lingredients.extend(is_)
|
|
for x in is_:
|
|
ingredients.add(x)
|
|
for a2 in a.split(', '):
|
|
idict[a2].append(is_)
|
|
|
|
allergens = set()
|
|
hazzard = collections.defaultdict(list)
|
|
for allergen, t in idict.items():
|
|
v = set(t[0])
|
|
for tt in t[1:]:
|
|
v = v.intersection(tt)
|
|
for x in v:
|
|
allergens.add(x)
|
|
for x in v:
|
|
hazzard[x].append(allergen)
|
|
count = 0
|
|
for l in lingredients:
|
|
if l not in allergens:
|
|
count += 1
|
|
print(count)
|
|
return hazzard
|
|
|
|
|
|
def p2(hazzard):
|
|
while any(map(lambda x: len(x)>1, hazzard.values())):
|
|
hazzard2 = {}
|
|
for i, a in hazzard.items():
|
|
for a2 in filter(lambda x: len(x) == 1, hazzard.values()):
|
|
if a == a2:
|
|
continue
|
|
v = set(a).symmetric_difference(a2) & set(a)
|
|
if len(v) <= len(hazzard[i]) and len(v) > 0:
|
|
if i in hazzard2:
|
|
hazzard2[i] = list(v.intersection(hazzard2[i]))
|
|
else:
|
|
hazzard2[i] = list(v)
|
|
if i not in hazzard2:
|
|
hazzard2[i] = hazzard[i]
|
|
hazzard = hazzard2
|
|
print(','.join([x[0] for x in sorted(hazzard.items(), key=lambda x: x[1])]))
|
|
|
|
|
|
return 0
|
|
|
|
result1 = None
|
|
if part_one():
|
|
start = time.time()
|
|
result1 = p1()
|
|
print(round(1000*(time.time() - start), 2), 'ms')
|
|
|
|
|
|
if part_two():
|
|
start = time.time()
|
|
p2(result1)
|
|
print(round(1000*(time.time() - start), 2), 'ms')
|
|
|
|
|