From cb247a773dfb1550621a5fa7cffb7473ac04aa99 Mon Sep 17 00:00:00 2001 From: Tom van der Lee Date: Mon, 31 Oct 2022 10:52:05 +0100 Subject: Added day 16 --- day16/__init__.py | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ day16/example.txt | 1 + day16/input.txt | 1 + 3 files changed, 132 insertions(+) create mode 100644 day16/__init__.py create mode 100644 day16/example.txt create mode 100644 day16/input.txt (limited to 'day16') diff --git a/day16/__init__.py b/day16/__init__.py new file mode 100644 index 0000000..66c0d36 --- /dev/null +++ b/day16/__init__.py @@ -0,0 +1,130 @@ +import math +from abc import ABC +from dataclasses import dataclass +from typing import List, Tuple, Iterator, TypedDict, Dict, Union + +from aoc import BaseAssignment + +@dataclass +class Packet: + raw: str + version: int = None + type: int = None + length_type = str + padding: int = 0 + payload_length = None + payload_start = None + payload: Union[int, List['Packet']] = None + + LITERAL = 4 + + FIFTEEN = '0' + ELEVEN = '1' + + PAYLOAD_LENGTH_TYPE = { + FIFTEEN: 15, + ELEVEN: 11 + } + + @classmethod + def from_hex(cls, value: str) -> 'Packet': + print() + print(value) + for byte in value: + print(byte, bin(int(byte, 16))[2:].rjust(4, '0')) + + bits = ''.join([ + bin(int(byte, 16))[2:] + .rjust(4, '0') + for byte + in value + ]) + + return cls( + raw=bits + ) + + + def __post_init__(self): + self.version = int(self.raw[:3], 2) + self.type = int(self.raw[3:6], 2) + + match self.type: + case self.LITERAL: + self.payload = self.parse_literal() + case _: + self.length_type = self.raw[6] + self.payload_start = 8 + self.PAYLOAD_LENGTH_TYPE[self.length_type] + self.payload_length = int(self.raw[8:self.payload_start], 2) + + print(self.raw[:3], self.raw[3:6], self.raw[7], self.raw[7:self.payload_start], self.raw[self.payload_start:]) + + self.payload = self.parse_operator() + + + def __len__(self): + return len(self.raw) - self.padding + + def pad(self): + added_zeroes = 4 - len(self.raw) % 4 + self.raw += added_zeroes * '0' + self.padding = added_zeroes + + def parse_literal(self) -> int: + start_index = 6 + + end = False + bits = [] + + while not end: + bits.append(self.raw[start_index + 1:start_index + 5]) + if self.raw[start_index] == '0': + end = True + + start_index += 5 + + self.raw = self.raw[:start_index] + self.pad() + + return int(''.join(bits), 2) + + def parse_operator(self) -> List['Packet']: + packets = [] + payload_end = self.payload_start + self.payload_length + payload = self.raw[self.payload_start:payload_end] + + while len(payload) > 0: + packets.append(Packet(raw=payload)) + payload = payload[len(packets[-1]):] + + self.raw = self.raw[:payload_end] + self.pad() + + return packets + + +class Assignment(BaseAssignment, ABC): + def parse_item(self, item: str) -> Packet: + return Packet.from_hex(item) + + + def read_input(self, example=False) -> Packet: + return next(super().read_input(example)) + +class AssignmentOne(Assignment): + example_result = 31 + + def version_sum(self, packet: Packet): + if packet.type == Packet.LITERAL: + return packet.version + + return packet.version + sum( + self.version_sum(p) + for p in packet.payload + ) + + def run(self, input: Packet): + return self.version_sum(input) + + + diff --git a/day16/example.txt b/day16/example.txt new file mode 100644 index 0000000..0d2cbff --- /dev/null +++ b/day16/example.txt @@ -0,0 +1 @@ +8A004A801A8002F478 diff --git a/day16/input.txt b/day16/input.txt new file mode 100644 index 0000000..3c7410e --- /dev/null +++ b/day16/input.txt @@ -0,0 +1 @@ +620D49005AD2245800D0C9E72BD279CAFB0016B1FA2B1802DC00D0CC611A47FCE2A4ACE1DD144BFABBFACA002FB2C6F33DFF4A0C0119B169B013005F003720004263644384800087C3B8B51C26B449130802D1A0068A5BD7D49DE793A48B5400D8293B1F95C5A3005257B880F5802A00084C788AD0440010F8490F608CACE034401AB4D0F5802726B3392EE2199628CEA007001884005C92015CC8051800130EC0468A01042803B8300D8E200788018C027890088CE0049006028012AB00342A0060801B2EBE400424933980453EFB2ABB36032274C026E4976001237D964FF736AFB56F254CB84CDF136C1007E7EB42298FE713749F973F7283005656F902A004067CD27CC1C00D9CB5FDD4D0014348010C8331C21710021304638C513006E234308B060094BEB76CE3966AA007C6588A5670DC3754395485007A718A7F149CA2DD3B6E7B777800118E7B59C0ECF5AE5D3B6CB1496BAE53B7ADD78C013C00CD2629BF5371D1D4C537EA6E3A3E95A3E180592AC7246B34032CF92804001A1CCF9BA521782ECBD69A98648BC18025800F8C9C37C827CA7BEFB31EADF0AE801BA42B87935B8EF976194EEC426AAF640168CECAF84BC004AE7D1673A6A600B4AB65802D230D35CF81B803D3775683F3A3860087802132FB32F322C92A4C402524F2DE006E8000854378F710C0010D8F30FE224AE428C015E00D40401987F06E3600021D0CE3EC228DA000574E4C3080182931E936E953B200BF656E15400D3496E4A725B92998027C00A84EEEE6B347D30BE60094E537AA73A1D600B880371AA36C3200043235C4C866C018E4963B7E7AA2B379918C639F1550086064BB148BA499EC731004E1AC966BDBC7646600C080370822AC4C1007E38C428BE0008741689D0ECC01197CF216EA16802D3748FE91B25CAF6D5F11C463004E4FD08FAF381F6004D3232CC93E7715B463F780 -- cgit v1.2.3