You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
68 lines
2.2 KiB
68 lines
2.2 KiB
#!/usr/bin/env python3
|
|
|
|
import sys
|
|
from bitstring import BitArray
|
|
from operator import mul
|
|
from functools import reduce
|
|
|
|
def parse_packet(packet, s, np=100000000, length=1000000000):
|
|
nex = s
|
|
end = s+length-1
|
|
bv = 0
|
|
numbers = []
|
|
while np > 0 and nex < min(len(packet)+1,end):
|
|
if (len(packet[nex:end+1]) == 0 or int(''.join(packet[nex:end+1]),2) == 0 or int(''.join(packet[nex:]),2) == 0):
|
|
if length < 1000000000: nex = end+1
|
|
break
|
|
v = int(''.join(packet[nex:nex+3]),2)
|
|
bv += v
|
|
t = int(''.join(packet[nex+3:nex+6]),2)
|
|
nex += 6
|
|
if t == 4:
|
|
num = []
|
|
while (n := packet[nex]) == '1':
|
|
num.append(list(packet[nex+1:nex+5]))
|
|
nex += 5
|
|
num.append(list(packet[nex+1:nex+5]))
|
|
nex += 5
|
|
i = int(''.join([''.join(n) for n in num]),2)
|
|
numbers.append(i)
|
|
else:
|
|
I = packet[nex]
|
|
nex += 1
|
|
if I == '1':
|
|
l = int(''.join(packet[nex:nex+11]),2)
|
|
nex += 11
|
|
b, nex, numbs = parse_packet(packet, nex, np=l)
|
|
bv += b
|
|
elif I == '0':
|
|
l = int(''.join(packet[nex:nex+15]),2)
|
|
nex += 15
|
|
b, nex, numbs = parse_packet(packet, nex, length=l)
|
|
bv += b
|
|
if t == 0: numbers.append(sum(numbs))
|
|
elif t == 1: numbers.append(reduce(mul, numbs, 1))
|
|
elif t == 2: numbers.append(min(numbs))
|
|
elif t == 3: numbers.append(max(numbs))
|
|
elif t == 5: numbers.append(int(numbs[0] > numbs[1]))
|
|
elif t == 6: numbers.append(int(numbs[0] < numbs[1]))
|
|
elif t == 7: numbers.append(int(numbs[0] == numbs[1]))
|
|
|
|
np -= 1
|
|
return bv, nex, numbers
|
|
|
|
if __name__ == '__main__':
|
|
hexa = [list(line.strip('\n')) for line in open(sys.argv[1])]
|
|
bits = [list(BitArray(hex=c).bin) for c in hexa[0]]
|
|
bits = [b for l in bits for b in l]
|
|
|
|
bv, _, num = parse_packet(bits,0,np=1)
|
|
|
|
# challenge 1
|
|
res1 = str(bv)
|
|
print("challenge 1:" + "\n" + res1 + "\n")
|
|
|
|
# challenge 2
|
|
res2 = str(num[0])
|
|
print("challenge 2:" + "\n" + res2 + "\n")
|
|
|
|
|