from collections import Counter from itertools import chain from utils import open_day from enum import IntEnum fset = frozenset Seg = IntEnum('Seg', [(n, 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: fset((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])] B = countmap[len(seg[Seg.B])] E = countmap[len(seg[Seg.E])] F = countmap[len(seg[Seg.F])] A = ACF - CF C = CF - F D = BCDF - CF - B G = ABCDEFG - A - BCDF - E segmap = [ A, B, C, D, E, F, G ] digmap = { fset(next(iter(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)