58 lines
1.5 KiB
Python
58 lines
1.5 KiB
Python
|
#!/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}")
|