Optimize 16

This commit is contained in:
2021-12-16 19:52:17 +01:00
parent 62c6995eab
commit f78fa5d772

View File

@@ -1,8 +1,11 @@
import sys import sys
from math import prod from math import prod
from typing import Callable
operator_func = Callable[[list[int]], int]
LITERAL = 4 LITERAL = 4
OPERATOR = { OPERATOR: dict[int, operator_func] = {
0: sum, 0: sum,
1: prod, 1: prod,
2: min, 2: min,
@@ -15,12 +18,12 @@ OPERATOR = {
total_version = 0 total_version = 0
def read_bits(bits, start, n) -> tuple[str, int]: def read_bits(bits: str, start: int, n: int) -> tuple[str, int]:
end = start + n end = start + n
return bits[start:end], end return bits[start:end], end
def read_bits_int(bits, start, n) -> tuple[int, int]: def read_bits_int(bits: str, start: int, n: int) -> tuple[int, int]:
number_bits, pos = read_bits(bits, start, n) number_bits, pos = read_bits(bits, start, n)
return int(number_bits, base=2), pos return int(number_bits, base=2), pos
@@ -33,33 +36,27 @@ def hex_string_to_bit_string(hex_string: str) -> str:
return "".join([hex_to_bits(x) for x in list(hex_string)]) return "".join([hex_to_bits(x) for x in list(hex_string)])
def parse_packet(bits) -> int: def parse_packet(bits: str) -> tuple[int, int]:
pos = 0 pos = 0
packet_version, _ = read_bits_int(bits, pos, 3) packet_version, pos = read_bits_int(bits, pos, 3)
global total_version global total_version
total_version += packet_version total_version += packet_version
type_ID, _ = read_bits_int(bits[3:], pos, 3) type_ID, pos = read_bits_int(bits, pos, 3)
if type_ID == LITERAL: if type_ID == LITERAL:
# print("Found: literal")
value, next_pos = parse_literal(bits[pos:]) value, next_pos = parse_literal(bits[pos:])
# print("literal:", value)
else: else:
# print("found: operator") value, next_pos = parse_operator(bits[pos:], type_ID)
value, next_pos = parse_operator(bits[pos:])
pos += next_pos pos += next_pos
return value, pos return value, pos
def parse_literal(bits) -> tuple[int, int]: def parse_literal(bits: str) -> tuple[int, int]:
pos = 0 pos = 0
packet_version, pos = read_bits_int(bits, pos, 3)
type_ID, pos = read_bits_int(bits, pos, 3)
number = "" number = ""
@@ -76,33 +73,26 @@ def parse_literal(bits) -> tuple[int, int]:
return int(number, base=2), pos return int(number, base=2), pos
def parse_operator(bits) -> int: def parse_operator(bits: str, type_ID: int) -> tuple[int, int]:
pos = 0 length_type_id = bits[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 = 1
pos = 7
parts = [] parts = []
if length_type_id == "0": if length_type_id == "0":
total_length, pos = read_bits_int(bits, pos, 15) total_length, pos = read_bits_int(bits, pos, 15)
# print("total length:", total_length)
read = 0 read = 0
while read != total_length: while read != total_length:
value, just_read = parse_packet(bits[pos:]) value, just_read = parse_packet(bits[pos:])
read += just_read read += just_read
# print(f"Length was: {just_read}, total: {read} of {total_length}")
pos += just_read pos += just_read
parts.append(value) parts.append(value)
else: else:
number_of_subs, pos = read_bits_int(bits, pos, 11) number_of_subs, pos = read_bits_int(bits, pos, 11)
# print("number of subs:", number_of_subs)
for i in range(number_of_subs): for _ in range(number_of_subs):
value, next_pos = parse_packet(bits[pos:]) value, next_pos = parse_packet(bits[pos:])
parts.append(value) parts.append(value)
pos += next_pos pos += next_pos
@@ -116,7 +106,7 @@ if __name__ == "__main__":
hex_string = sys.stdin.readline().strip() hex_string = sys.stdin.readline().strip()
bits = hex_string_to_bit_string(hex_string) bits = hex_string_to_bit_string(hex_string)
value, _ = parse_operator(bits) value, _ = parse_packet(bits)
print("part one:", total_version) print("part one:", total_version)
print("part two:", value) print("part two:", value)