from collections import Counter from itertools import chain from utils import open_day from enum import IntEnum fset = frozenset Seg = IntEnum('Seg', [(n, str(i)) for i, n in enumerate('ABCDEFG')]) dig = [ fset((Seg.A, Seg.B, Seg.C, Seg.E, Seg.F, Seg.G)), fset(( Seg.C, Seg.F )), fset((Seg.A, Seg.C, Seg.D, Seg.E, Seg.G)), fset((Seg.A, Seg.C, Seg.D, Seg.F, Seg.G)), fset(( Seg.B, Seg.C, Seg.D, Seg.F )), fset((Seg.A, Seg.B, Seg.D, Seg.F, Seg.G)), fset((Seg.A, Seg.B, Seg.D, Seg.E, Seg.F, Seg.G)), fset((Seg.A, Seg.C, Seg.F )), fset((Seg.A, Seg.B, Seg.C, Seg.D, Seg.E, Seg.F, Seg.G)), fset((Seg.A, Seg.B, Seg.C, Seg.D, Seg.F, Seg.G)), ] seg = [ fset(i for i in range(10) if seg in dig[i]) for seg in Seg ] counts = Counter() count = 0 with open_day(8) as f: for line in f: patterns, digits = line.rstrip().split(' | ') patterns = fset(fset(p) for p in patterns.split()) countmap = { count: seg for seg, count in Counter(chain.from_iterable(patterns)).items() } lenmap = { len(pat): pat for pat in patterns } CF = lenmap[len(dig[1])] BCDF = lenmap[len(dig[4])] ACF = lenmap[len(dig[7])] ABCDEFG = lenmap[len(dig[8])] segmap = dict() segmap[Seg.B] = countmap[len(seg[Seg.B])] segmap[Seg.E] = countmap[len(seg[Seg.E])] segmap[Seg.F] = countmap[len(seg[Seg.F])] def single(s): return next(iter(s)) segmap[Seg.A] = single(ACF - CF) segmap[Seg.C] = single(CF - fset(segmap[Seg.F])) segmap[Seg.D] = single(BCDF - CF - fset(segmap[Seg.B])) segmap[Seg.G] = single(ABCDEFG - fset(segmap.values())) digmap = { fset(segmap[s] for s in d): i for i, d in enumerate(dig) } digits = [ digmap[fset(d)] for d in digits.split() ] counts.update(digits) count += sum(d * 10 ** i for i, d in enumerate(reversed(digits))) print(counts[1] + counts[4] + counts[7] + counts[8]) print(count)