2
1
Fork 0
aoc2021/16/solution.py

58 lines
1.5 KiB
Python
Executable File

#!/usr/bin/env python3
import sys
from operator import mul
from functools import reduce
from itertools import tee, takewhile, islice
packet = sys.stdin.readline().rstrip()
bitstr = "".join([f"{int(x,16):04b}" for x in packet])
ops = {
0: sum,
1: lambda l: reduce(mul, l, 1),
2: min,
3: max,
5: lambda l: 1 if l[0] > l[1] else 0,
6: lambda l: 1 if l[0] < l[1] else 0,
7: lambda l: 1 if l[0] == l[1] else 0,
}
def decode(p):
ver = int(p[0:3],2)
pid = int(p[3:6],2)
versum = ver
if pid == 4:
a, b = tee(map(lambda b: (int(b[0],2), int("".join(b[1:]), 2)),
zip(*(iter(p[6:]),)*5)))
n = sum(takewhile(lambda s: s, map(lambda x: x[0], a))) + 1
val = reduce(lambda a, b: a << 4 | b[1], islice(b, n), 0)
plen = 6 + n * 5
return plen, val, ver
else:
typ = int(p[6],2)
rvals = []
start = 7+(11 if typ else 15)
plen = int(p[7:start],2)
if typ:
for i in range(plen):
l, v, vn = decode(p[start:])
rvals.append(v)
start += l
versum+=vn
else:
while plen:
l, v, vn = decode(p[start:start+plen])
rvals.append(v)
start += l
plen -= l
versum+=vn
rval = ops[pid](rvals)
return start, rval, versum
_, gold, silver = decode(bitstr)
print(f"Silver: {silver}\nGold: {gold}")