# Jour 16

unknown
python
2 years ago
2.4 kB
1
Indexable
Never
```from aoc_get import get_input
from functools import reduce

def binarize(x: int):
binary = bin(x)[2:]
mod = len(binary) % 4
padding = 0 if mod == 0 else 4 - mod
return '0' * padding + binary

inp = get_input()
binary = binarize(int(inp, 16))
p1 = 0

class PacketNode:
def __init__(self, i):
self.length = 0
self.start = i
self.type = int(binary[i + 3:i + 6], 2)
self.version = int(binary[i:i + 3], 2)
global p1
p1 += self.version

if self.type == 4:
self.value = self.get_value(self.start + 6)

elif binary[i + 6] == '0':
self.sub_bits = int(binary[i + 7:i + 22], 2)
max_i = i + 22 + self.sub_bits
self.children = []
i += 22
while i < max_i:
pn = PacketNode(i)
self.children.append(pn)
i += pn.length
self.length = i - self.start

elif binary[i + 6] == '1':
self.num_subs = int(binary[i + 7:i + 18], 2)
self.children = []
i += 18
packet_count = 0
while packet_count < self.num_subs:
pn = PacketNode(i)
self.children.append(pn)
i += pn.length
packet_count += 1
self.length = i - self.start

def eval(self):
if self.type == 4:
return self.value
values = [c.eval() for c in self.children]

if self.type == 0:
return reduce(lambda x, y: x + y, values)
elif self.type == 1:
return reduce(lambda x, y: x * y, values)
elif self.type == 2:
return reduce(min, values)
elif self.type == 3:
return reduce(max, values)
elif self.type == 5:
return reduce(lambda x, y: x > y, values)
elif self.type == 6:
return reduce(lambda x, y: x < y, values)
elif self.type == 7:
return reduce(lambda x, y: x == y, values)

def get_value(self, i):
value_string = ''
while binary[i] == '1':
value_string += binary[i + 1:i + 5]
i += 5
value_string += binary[i + 1:i + 5]
self.length += i + 5 - self.start
mod = self.length % 4
return int(value_string, 2)

root = PacketNode(0)

print(p1)
p2 = root.eval()
print(p2)
```