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