16!
This commit is contained in:
122
16/16.py
Normal file
122
16/16.py
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
import sys
|
||||||
|
from math import prod
|
||||||
|
|
||||||
|
LITERAL = 4
|
||||||
|
OPERATOR = {
|
||||||
|
0: sum,
|
||||||
|
1: prod,
|
||||||
|
2: min,
|
||||||
|
3: max,
|
||||||
|
5: lambda lst: int(lst[0] > lst[1]),
|
||||||
|
6: lambda lst: int(lst[0] < lst[1]),
|
||||||
|
7: lambda lst: int(lst[0] == lst[1]),
|
||||||
|
}
|
||||||
|
|
||||||
|
total_version = 0
|
||||||
|
|
||||||
|
|
||||||
|
def read_bits(bits, start, n) -> tuple[str, int]:
|
||||||
|
end = start + n
|
||||||
|
return bits[start:end], end
|
||||||
|
|
||||||
|
|
||||||
|
def read_bits_int(bits, start, n) -> tuple[int, int]:
|
||||||
|
number_bits, pos = read_bits(bits, start, n)
|
||||||
|
return int(number_bits, base=2), pos
|
||||||
|
|
||||||
|
|
||||||
|
def hex_to_bits(hex: str) -> str:
|
||||||
|
return format(int(hex, base=16), "04b")
|
||||||
|
|
||||||
|
|
||||||
|
def hex_string_to_bit_string(hex_string: str) -> str:
|
||||||
|
return "".join([hex_to_bits(x) for x in list(hex_string)])
|
||||||
|
|
||||||
|
|
||||||
|
def parse_packet(bits) -> int:
|
||||||
|
pos = 0
|
||||||
|
packet_version, _ = read_bits_int(bits, pos, 3)
|
||||||
|
|
||||||
|
global total_version
|
||||||
|
total_version += packet_version
|
||||||
|
|
||||||
|
type_ID, _ = read_bits_int(bits[3:], pos, 3)
|
||||||
|
|
||||||
|
if type_ID == LITERAL:
|
||||||
|
# print("Found: literal")
|
||||||
|
value, next_pos = parse_literal(bits[pos:])
|
||||||
|
# print("literal:", value)
|
||||||
|
else:
|
||||||
|
# print("found: operator")
|
||||||
|
value, next_pos = parse_operator(bits[pos:])
|
||||||
|
|
||||||
|
pos += next_pos
|
||||||
|
|
||||||
|
return value, pos
|
||||||
|
|
||||||
|
|
||||||
|
def parse_literal(bits) -> tuple[int, int]:
|
||||||
|
pos = 0
|
||||||
|
packet_version, pos = read_bits_int(bits, pos, 3)
|
||||||
|
|
||||||
|
type_ID, pos = read_bits_int(bits, pos, 3)
|
||||||
|
|
||||||
|
number = ""
|
||||||
|
|
||||||
|
done = False
|
||||||
|
|
||||||
|
while not done:
|
||||||
|
part, pos = read_bits(bits, pos, 5)
|
||||||
|
|
||||||
|
if part[0] == "0":
|
||||||
|
done = True
|
||||||
|
|
||||||
|
number += part[1:]
|
||||||
|
|
||||||
|
return int(number, base=2), pos
|
||||||
|
|
||||||
|
|
||||||
|
def parse_operator(bits) -> int:
|
||||||
|
pos = 0
|
||||||
|
packet_version, pos = read_bits_int(bits, pos, 3)
|
||||||
|
type_ID, pos = read_bits_int(bits, pos, 3)
|
||||||
|
|
||||||
|
length_type_id = bits[6]
|
||||||
|
|
||||||
|
pos = 7
|
||||||
|
|
||||||
|
parts = []
|
||||||
|
|
||||||
|
if length_type_id == "0":
|
||||||
|
total_length, pos = read_bits_int(bits, pos, 15)
|
||||||
|
# print("total length:", total_length)
|
||||||
|
read = 0
|
||||||
|
|
||||||
|
while read != total_length:
|
||||||
|
value, just_read = parse_packet(bits[pos:])
|
||||||
|
read += just_read
|
||||||
|
# print(f"Length was: {just_read}, total: {read} of {total_length}")
|
||||||
|
pos += just_read
|
||||||
|
parts.append(value)
|
||||||
|
else:
|
||||||
|
number_of_subs, pos = read_bits_int(bits, pos, 11)
|
||||||
|
# print("number of subs:", number_of_subs)
|
||||||
|
|
||||||
|
for i in range(number_of_subs):
|
||||||
|
value, next_pos = parse_packet(bits[pos:])
|
||||||
|
parts.append(value)
|
||||||
|
pos += next_pos
|
||||||
|
|
||||||
|
calculated = OPERATOR[type_ID](parts)
|
||||||
|
|
||||||
|
return calculated, pos
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
hex_string = sys.stdin.readline().strip()
|
||||||
|
bits = hex_string_to_bit_string(hex_string)
|
||||||
|
|
||||||
|
value, _ = parse_operator(bits)
|
||||||
|
|
||||||
|
print("part one:", total_version)
|
||||||
|
print("part two:", value)
|
||||||
0
16/ex16.in
Normal file
0
16/ex16.in
Normal file
1
16/input16.in
Normal file
1
16/input16.in
Normal file
@@ -0,0 +1 @@
|
|||||||
|
6051639005B56008C1D9BB3CC9DAD5BE97A4A9104700AE76E672DC95AAE91425EF6AD8BA5591C00F92073004AC0171007E0BC248BE0008645982B1CA680A7A0CC60096802723C94C265E5B9699E7E94D6070C016958F99AC015100760B45884600087C6E88B091C014959C83E740440209FC89C2896A50765A59CE299F3640D300827902547661964D2239180393AF92A8B28F4401BCC8ED52C01591D7E9D2591D7E9D273005A5D127C99802C095B044D5A19A73DC0E9C553004F000DE953588129E372008F2C0169FDB44FA6C9219803E00085C378891F00010E8FF1AE398803D1BE25C743005A6477801F59CC4FA1F3989F420C0149ED9CF006A000084C5386D1F4401F87310E313804D33B4095AFBED32ABF2CA28007DC9D3D713300524BCA940097CA8A4AF9F4C00F9B6D00088654867A7BC8BCA4829402F9D6895B2E4DF7E373189D9BE6BF86B200B7E3C68021331CD4AE6639A974232008E663C3FE00A4E0949124ED69087A848002749002151561F45B3007218C7A8FE600FC228D50B8C01097EEDD7001CF9DE5C0E62DEB089805330ED30CD3C0D3A3F367A40147E8023221F221531C9681100C717002100B36002A19809D15003900892601F950073630024805F400150D400A70028C00F5002C00252600698400A700326C0E44590039687B313BF669F35C9EF974396EF0A647533F2011B340151007637C46860200D43085712A7E4FE60086003E5234B5A56129C91FC93F1802F12EC01292BD754BCED27B92BD754BCED27B100264C4C40109D578CA600AC9AB5802B238E67495391D5CFC402E8B325C1E86F266F250B77ECC600BE006EE00085C7E8DF044001088E31420BCB08A003A72BF87D7A36C994CE76545030047801539F649BF4DEA52CBCA00B4EF3DE9B9CFEE379F14608
|
||||||
Reference in New Issue
Block a user