This commit is contained in:
114
day-16/day-16.py
Normal file
114
day-16/day-16.py
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
from pathlib import Path
|
||||||
|
from math import prod
|
||||||
|
|
||||||
|
|
||||||
|
def get_next_packet(msg, start, packets, res=0):
|
||||||
|
idx = start
|
||||||
|
if (idx+11) >= len(msg):
|
||||||
|
idx = -1
|
||||||
|
return idx, res
|
||||||
|
version = int(msg[idx:idx + 3], 2)
|
||||||
|
idx += 3
|
||||||
|
res += version
|
||||||
|
type_id = int(msg[idx:idx + 3], 2)
|
||||||
|
idx += 3
|
||||||
|
payload = None
|
||||||
|
match type_id:
|
||||||
|
case 4:
|
||||||
|
# literal
|
||||||
|
end = False
|
||||||
|
literal = 0
|
||||||
|
while not end:
|
||||||
|
if not int(msg[idx:idx + 1], 2):
|
||||||
|
end = True
|
||||||
|
idx += 1
|
||||||
|
literal = (literal << 4) | int(msg[idx:idx + 4], 2)
|
||||||
|
idx += 4
|
||||||
|
payload = literal
|
||||||
|
# print('l', version, type_id, literal)
|
||||||
|
case _:
|
||||||
|
length_id = int(msg[idx:idx + 1], 2)
|
||||||
|
idx += 1
|
||||||
|
length = 0
|
||||||
|
payload = []
|
||||||
|
if length_id:
|
||||||
|
length = int(msg[idx:idx + 11], 2)
|
||||||
|
idx += 11
|
||||||
|
# print('o', version, type_id, length_id, length)
|
||||||
|
for _ in range(length):
|
||||||
|
idx, res = get_next_packet(msg, idx, payload, res)
|
||||||
|
else:
|
||||||
|
length = int(msg[idx:idx + 15], 2)
|
||||||
|
idx += 15
|
||||||
|
# print('o', version, type_id, length_id, length)
|
||||||
|
next_idx = idx + length
|
||||||
|
while idx < next_idx:
|
||||||
|
idx, res = get_next_packet(msg, idx, payload, res)
|
||||||
|
packets.append({'version': version, 'type_id': type_id, 'payload': payload})
|
||||||
|
return idx, res
|
||||||
|
|
||||||
|
|
||||||
|
def calc_result(packets):
|
||||||
|
res = 0
|
||||||
|
for p in packets:
|
||||||
|
match p['type_id']:
|
||||||
|
case 4:
|
||||||
|
res = p['payload']
|
||||||
|
case _:
|
||||||
|
sub_packets = []
|
||||||
|
for i in range(len(p['payload'])):
|
||||||
|
sub_packets.append(calc_result([p['payload'][i]]))
|
||||||
|
match p['type_id']:
|
||||||
|
case 0:
|
||||||
|
res = sum(sub_packets)
|
||||||
|
case 1:
|
||||||
|
res = prod(sub_packets)
|
||||||
|
case 2:
|
||||||
|
res = min(sub_packets)
|
||||||
|
case 3:
|
||||||
|
res = max(sub_packets)
|
||||||
|
case 5:
|
||||||
|
res = 1 if sub_packets[0] > sub_packets[1] else 0
|
||||||
|
case 6:
|
||||||
|
res = 1 if sub_packets[0] < sub_packets[1] else 0
|
||||||
|
case 7:
|
||||||
|
res = 1 if sub_packets[0] == sub_packets[1] else 0
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
def part_1(input):
|
||||||
|
result = 0
|
||||||
|
line = input[0].rstrip().strip('0')
|
||||||
|
msg = bin(int(line, 16))
|
||||||
|
msg = msg[2:]
|
||||||
|
while len(msg) % 4:
|
||||||
|
msg = '0' + msg
|
||||||
|
packets = []
|
||||||
|
next = 0
|
||||||
|
while -1 != next:
|
||||||
|
next, result = get_next_packet(msg, next, packets, result)
|
||||||
|
print("Part 1 result:", result)
|
||||||
|
|
||||||
|
|
||||||
|
def part_2(input):
|
||||||
|
result = 0
|
||||||
|
line = input[0].rstrip().strip('0')
|
||||||
|
msg = bin(int(line, 16))
|
||||||
|
msg = msg[2:]
|
||||||
|
while len(msg) % 4:
|
||||||
|
msg = '0' + msg
|
||||||
|
packets = []
|
||||||
|
next = 0
|
||||||
|
while -1 != next:
|
||||||
|
next, _ = get_next_packet(msg, next, packets)
|
||||||
|
result = calc_result(packets)
|
||||||
|
print("Part 2 result:", result)
|
||||||
|
|
||||||
|
|
||||||
|
input = list()
|
||||||
|
p = Path(__file__).with_name('input.txt')
|
||||||
|
with open(p) as f:
|
||||||
|
input = f.readlines()
|
||||||
|
part_1(input)
|
||||||
|
part_2(input)
|
||||||
1
day-16/input.txt
Normal file
1
day-16/input.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
E058F79802FA00A4C1C496E5C738D860094BDF5F3ED004277DD87BB36C8EA800BDC3891D4AFA212012B64FE21801AB80021712E3CC771006A3E47B8811E4C01900043A1D41686E200DC4B8DB06C001098411C22B30085B2D6B743A6277CF719B28C9EA11AEABB6D200C9E6C6F801F493C7FE13278FFC26467C869BC802839E489C19934D935C984B88460085002F931F7D978740668A8C0139279C00D40401E8D1082318002111CE0F460500BE462F3350CD20AF339A7BB4599DA7B755B9E6B6007D25E87F3D2977543F00016A2DCB029009193D6842A754015CCAF652D6609D2F1EE27B28200C0A4B1DFCC9AC0109F82C4FC17880485E00D4C0010F8D110E118803F0DA1845A932B82E200D41E94AD7977699FED38C0169DD53B986BEE7E00A49A2CE554A73D5A6ED2F64B4804419508B00584019877142180803715224C613009E795E58FA45EA7C04C012D004E7E3FE64C27E3FE64C24FA5D331CFB024E0064DEEB49D0CC401A2004363AC6C8344008641B8351B08010882917E3D1801D2C7CA0124AE32DD3DDE86CF52BBFAAC2420099AC01496269FD65FA583A5A9ECD781A20094CE10A73F5F4EB450200D326D270021A9F8A349F7F897E85A4020CF802F238AEAA8D22D1397BF27A97FD220898600C4926CBAFCD1180087738FD353ECB7FDE94A6FBCAA0C3794875708032D8A1A0084AE378B994AE378B9A8007CD370A6F36C17C9BFCAEF18A73B2028C0A004CBC7D695773FAF1006E52539D2CFD800D24B577E1398C259802D3D23AB00540010A8611260D0002130D23645D3004A6791F22D802931FA4E46B31FA4E4686004A8014805AE0801AC050C38010600580109EC03CC200DD40031F100B166005200898A00690061860072801CE007B001573B5493004248EA553E462EC401A64EE2F6C7E23740094C952AFF031401A95A7192475CACF5E3F988E29627600E724DBA14CBE710C2C4E72302C91D12B0063F2BBFFC6A586A763B89C4DC9A0
|
||||||
Reference in New Issue
Block a user