From 978e47db5b7036e708d3c4949748b7d824f346a9 Mon Sep 17 00:00:00 2001 From: Stefan Harmuth Date: Thu, 16 Dec 2021 09:05:38 +0100 Subject: [PATCH] day16: version 1 --- day16.py | 125 ++++++++++++++++++++++++++++++++++++++++ inputs/input16 | 1 + inputs/test_input16_1_0 | 1 + inputs/test_input16_1_1 | 1 + inputs/test_input16_1_2 | 1 + inputs/test_input16_1_3 | 1 + inputs/test_input16_1_4 | 1 + inputs/test_input16_2_0 | 1 + inputs/test_input16_2_1 | 1 + inputs/test_input16_2_2 | 1 + inputs/test_input16_2_3 | 1 + inputs/test_input16_2_4 | 1 + inputs/test_input16_2_5 | 1 + inputs/test_input16_2_6 | 1 + inputs/test_input16_2_7 | 1 + inputs/test_input16_2_8 | 1 + 16 files changed, 140 insertions(+) create mode 100644 day16.py create mode 100644 inputs/input16 create mode 100644 inputs/test_input16_1_0 create mode 100644 inputs/test_input16_1_1 create mode 100644 inputs/test_input16_1_2 create mode 100644 inputs/test_input16_1_3 create mode 100644 inputs/test_input16_1_4 create mode 100644 inputs/test_input16_2_0 create mode 100644 inputs/test_input16_2_1 create mode 100644 inputs/test_input16_2_2 create mode 100644 inputs/test_input16_2_3 create mode 100644 inputs/test_input16_2_4 create mode 100644 inputs/test_input16_2_5 create mode 100644 inputs/test_input16_2_6 create mode 100644 inputs/test_input16_2_7 create mode 100644 inputs/test_input16_2_8 diff --git a/day16.py b/day16.py new file mode 100644 index 0000000..835c847 --- /dev/null +++ b/day16.py @@ -0,0 +1,125 @@ +from math import prod + +from tools.aoc import AOCDay +from typing import Any, List + + +def get_packet(bit_rep: str) -> (int, int, str, int): # version, type, packet, packet_length + msg_version = int(bit_rep[:3], 2) + msg_type = int(bit_rep[3:6], 2) + pkg_msg = "" + index = 6 + + if msg_type == 4: + while bit_rep[index] == "1": + pkg_msg += bit_rep[index+1:index+5] + index += 5 + pkg_msg += bit_rep[index:index + 5] + index += 5 + else: + op_type = bit_rep[index] + index += 1 + if op_type == "0": + sub_pkg_len = int(bit_rep[index:index+15], 2) + index += 15 + sub_pkg_len + else: + sub_pkg_count = int(bit_rep[index:index+11], 2) + index += 11 + for x in range(sub_pkg_count): + _, _, _, sub_pkg_len = get_packet(bit_rep[index:]) + index += sub_pkg_len + + return msg_version, msg_type, bit_rep[:index], index + + +def get_subpackages(packet: str) -> List[str]: + ptype = int(packet[3:6], 2) + if ptype == 4: + return [packet] + else: + plist = [] + op_type = packet[6] + if op_type == "0": + sub_pkg_len = int(packet[7:22], 2) + sub_packages = packet[22:22+sub_pkg_len] + while "1" in sub_packages: + _, _, sub_packet, sub_pkg_len = get_packet(sub_packages) + sub_packages = sub_packages[sub_pkg_len:] + plist.append(sub_packet) + else: + sub_pkg_count = int(packet[7:18], 2) + index = 18 + for x in range(sub_pkg_count): + _, _, sub_packet, sub_pkg_len = get_packet(packet[index:]) + index += sub_pkg_len + plist.append(sub_packet) + + return plist + + +def get_versions(packet: str) -> int: + version = int(packet[0:3], 2) + ptype = int(packet[3:6], 2) + if ptype == 4: + return version + else: + for p in get_subpackages(packet): + version += get_versions(p) + + return version + + +def get_value(packet: str) -> int: + while "1" in packet: + pkg_version, pkg_type, this_packet, pkg_len = get_packet(packet) + packet = packet[pkg_len:] + if pkg_type == 0: + return sum(get_value(p) for p in get_subpackages(this_packet)) + elif pkg_type == 1: + return prod(get_value(p) for p in get_subpackages(this_packet)) + elif pkg_type == 2: + return min(get_value(p) for p in get_subpackages(this_packet)) + elif pkg_type == 3: + return max(get_value(p) for p in get_subpackages(this_packet)) + elif pkg_type == 4: + index = 6 + pkg_bits = "" + while this_packet[index] == "1": + pkg_bits += this_packet[index + 1:index + 5] + index += 5 + pkg_bits += this_packet[index + 1:index + 5] + return int(pkg_bits, 2) + elif pkg_type == 5: + sub_pkg = get_subpackages(this_packet) + return get_value(sub_pkg[0]) > get_value(sub_pkg[1]) + elif pkg_type == 6: + sub_pkg = get_subpackages(this_packet) + return get_value(sub_pkg[0]) < get_value(sub_pkg[1]) + elif pkg_type == 7: + sub_pkg = get_subpackages(this_packet) + return get_value(sub_pkg[0]) == get_value(sub_pkg[1]) + + +class Day(AOCDay): + test_solutions_p1 = [16, 12, 23, 31, 1007] + test_solutions_p2 = [3, 54, 7, 9, 1, 0, 0, 1, 834151779165] + + def part1(self) -> Any: + bit_rep = "" + for c in self.getInput(): + bit_rep += "{0:04b}".format(int(c, 16)) + + version_sum = 0 + while "1" in bit_rep: + pkg_version, pkg_type, packet, pkg_len = get_packet(bit_rep) + bit_rep = bit_rep[pkg_len:] + version_sum += get_versions(packet) + + return version_sum + + def part2(self) -> Any: + bit_rep = "" + for c in self.getInput(): + bit_rep += "{0:04b}".format(int(c, 16)) + + return get_value(bit_rep) diff --git a/inputs/input16 b/inputs/input16 new file mode 100644 index 0000000..559ec3b --- /dev/null +++ b/inputs/input16 @@ -0,0 +1 @@ +8054F9C95F9C1C973D000D0A79F6635986270B054AE9EE51F8001D395CCFE21042497E4A2F6200E1803B0C20846820043630C1F8A840087C6C8BB1688018395559A30997A8AE60064D17980291734016100622F41F8DC200F4118D3175400E896C068E98016E00790169A600590141EE0062801E8041E800F1A0036C28010402CD3801A60053007928018CA8014400EF2801D359FFA732A000D2623CADE7C907C2C96F5F6992AC440157F002032CE92CE9352AF9F4C0119BDEE93E6F9C55D004E66A8B335445009E1CCCEAFD299AA4C066AB1BD4C5804149C1193EE1967AB7F214CF74752B1E5CEDC02297838C649F6F9138300424B9C34B004A63CCF238A56B71520142A5A7FC672E5E00B080350663B44F1006A2047B8C51CC80286C0055253951F98469F1D86D3C1E600F80021118A124261006E23C7E8260008641A8D51F0C01299EC3F4B6A37CABD80252211221A600BC930D0057B2FAA31CDCEF6B76DADF1666FE2E000FA4905CB7239AFAC0660114B39C9BA492D4EBB180252E472AD6C00BF48C350F9F47D2012B6C014000436284628BE00087C5D8671F27F0C480259C9FE16D1F4B224942B6F39CAF767931CFC36BC800EA4FF9CE0CCE4FCA4600ACCC690DE738D39D006A000087C2A89D0DC401987B136259006AFA00ACA7DBA53EDB31F9F3DBF31900559C00BCCC4936473A639A559BC433EB625404300564D67001F59C8E3172892F498C802B1B0052690A69024F3C95554C0129484C370010196269D071003A079802DE0084E4A53E8CCDC2CA7350ED6549CEC4AC00404D3C30044D1BA78F25EF2CFF28A60084967D9C975003992DF8C240923C45300BE7DAA540E6936194E311802D800D2CB8FC9FA388A84DEFB1CB2CBCBDE9E9C8803A6B00526359F734673F28C367D2DE2F3005256B532D004C40198DF152130803D11211C7550056706E6F3E9D24B0 diff --git a/inputs/test_input16_1_0 b/inputs/test_input16_1_0 new file mode 100644 index 0000000..0d2cbff --- /dev/null +++ b/inputs/test_input16_1_0 @@ -0,0 +1 @@ +8A004A801A8002F478 diff --git a/inputs/test_input16_1_1 b/inputs/test_input16_1_1 new file mode 100644 index 0000000..ed3b78a --- /dev/null +++ b/inputs/test_input16_1_1 @@ -0,0 +1 @@ +620080001611562C8802118E34 diff --git a/inputs/test_input16_1_2 b/inputs/test_input16_1_2 new file mode 100644 index 0000000..827e51b --- /dev/null +++ b/inputs/test_input16_1_2 @@ -0,0 +1 @@ +C0015000016115A2E0802F182340 diff --git a/inputs/test_input16_1_3 b/inputs/test_input16_1_3 new file mode 100644 index 0000000..0a1278e --- /dev/null +++ b/inputs/test_input16_1_3 @@ -0,0 +1 @@ +A0016C880162017C3686B18A3D4780 diff --git a/inputs/test_input16_1_4 b/inputs/test_input16_1_4 new file mode 100644 index 0000000..559ec3b --- /dev/null +++ b/inputs/test_input16_1_4 @@ -0,0 +1 @@ +8054F9C95F9C1C973D000D0A79F6635986270B054AE9EE51F8001D395CCFE21042497E4A2F6200E1803B0C20846820043630C1F8A840087C6C8BB1688018395559A30997A8AE60064D17980291734016100622F41F8DC200F4118D3175400E896C068E98016E00790169A600590141EE0062801E8041E800F1A0036C28010402CD3801A60053007928018CA8014400EF2801D359FFA732A000D2623CADE7C907C2C96F5F6992AC440157F002032CE92CE9352AF9F4C0119BDEE93E6F9C55D004E66A8B335445009E1CCCEAFD299AA4C066AB1BD4C5804149C1193EE1967AB7F214CF74752B1E5CEDC02297838C649F6F9138300424B9C34B004A63CCF238A56B71520142A5A7FC672E5E00B080350663B44F1006A2047B8C51CC80286C0055253951F98469F1D86D3C1E600F80021118A124261006E23C7E8260008641A8D51F0C01299EC3F4B6A37CABD80252211221A600BC930D0057B2FAA31CDCEF6B76DADF1666FE2E000FA4905CB7239AFAC0660114B39C9BA492D4EBB180252E472AD6C00BF48C350F9F47D2012B6C014000436284628BE00087C5D8671F27F0C480259C9FE16D1F4B224942B6F39CAF767931CFC36BC800EA4FF9CE0CCE4FCA4600ACCC690DE738D39D006A000087C2A89D0DC401987B136259006AFA00ACA7DBA53EDB31F9F3DBF31900559C00BCCC4936473A639A559BC433EB625404300564D67001F59C8E3172892F498C802B1B0052690A69024F3C95554C0129484C370010196269D071003A079802DE0084E4A53E8CCDC2CA7350ED6549CEC4AC00404D3C30044D1BA78F25EF2CFF28A60084967D9C975003992DF8C240923C45300BE7DAA540E6936194E311802D800D2CB8FC9FA388A84DEFB1CB2CBCBDE9E9C8803A6B00526359F734673F28C367D2DE2F3005256B532D004C40198DF152130803D11211C7550056706E6F3E9D24B0 diff --git a/inputs/test_input16_2_0 b/inputs/test_input16_2_0 new file mode 100644 index 0000000..0ab8df5 --- /dev/null +++ b/inputs/test_input16_2_0 @@ -0,0 +1 @@ +C200B40A82 diff --git a/inputs/test_input16_2_1 b/inputs/test_input16_2_1 new file mode 100644 index 0000000..08def75 --- /dev/null +++ b/inputs/test_input16_2_1 @@ -0,0 +1 @@ +04005AC33890 diff --git a/inputs/test_input16_2_2 b/inputs/test_input16_2_2 new file mode 100644 index 0000000..c4d0ebb --- /dev/null +++ b/inputs/test_input16_2_2 @@ -0,0 +1 @@ +880086C3E88112 diff --git a/inputs/test_input16_2_3 b/inputs/test_input16_2_3 new file mode 100644 index 0000000..985c72d --- /dev/null +++ b/inputs/test_input16_2_3 @@ -0,0 +1 @@ +CE00C43D881120 diff --git a/inputs/test_input16_2_4 b/inputs/test_input16_2_4 new file mode 100644 index 0000000..408badd --- /dev/null +++ b/inputs/test_input16_2_4 @@ -0,0 +1 @@ +D8005AC2A8F0 diff --git a/inputs/test_input16_2_5 b/inputs/test_input16_2_5 new file mode 100644 index 0000000..eb83c7b --- /dev/null +++ b/inputs/test_input16_2_5 @@ -0,0 +1 @@ +F600BC2D8F diff --git a/inputs/test_input16_2_6 b/inputs/test_input16_2_6 new file mode 100644 index 0000000..6055bef --- /dev/null +++ b/inputs/test_input16_2_6 @@ -0,0 +1 @@ +9C005AC2F8F0 diff --git a/inputs/test_input16_2_7 b/inputs/test_input16_2_7 new file mode 100644 index 0000000..4ced67a --- /dev/null +++ b/inputs/test_input16_2_7 @@ -0,0 +1 @@ +9C0141080250320F1802104A08 diff --git a/inputs/test_input16_2_8 b/inputs/test_input16_2_8 new file mode 100644 index 0000000..559ec3b --- /dev/null +++ b/inputs/test_input16_2_8 @@ -0,0 +1 @@ +8054F9C95F9C1C973D000D0A79F6635986270B054AE9EE51F8001D395CCFE21042497E4A2F6200E1803B0C20846820043630C1F8A840087C6C8BB1688018395559A30997A8AE60064D17980291734016100622F41F8DC200F4118D3175400E896C068E98016E00790169A600590141EE0062801E8041E800F1A0036C28010402CD3801A60053007928018CA8014400EF2801D359FFA732A000D2623CADE7C907C2C96F5F6992AC440157F002032CE92CE9352AF9F4C0119BDEE93E6F9C55D004E66A8B335445009E1CCCEAFD299AA4C066AB1BD4C5804149C1193EE1967AB7F214CF74752B1E5CEDC02297838C649F6F9138300424B9C34B004A63CCF238A56B71520142A5A7FC672E5E00B080350663B44F1006A2047B8C51CC80286C0055253951F98469F1D86D3C1E600F80021118A124261006E23C7E8260008641A8D51F0C01299EC3F4B6A37CABD80252211221A600BC930D0057B2FAA31CDCEF6B76DADF1666FE2E000FA4905CB7239AFAC0660114B39C9BA492D4EBB180252E472AD6C00BF48C350F9F47D2012B6C014000436284628BE00087C5D8671F27F0C480259C9FE16D1F4B224942B6F39CAF767931CFC36BC800EA4FF9CE0CCE4FCA4600ACCC690DE738D39D006A000087C2A89D0DC401987B136259006AFA00ACA7DBA53EDB31F9F3DBF31900559C00BCCC4936473A639A559BC433EB625404300564D67001F59C8E3172892F498C802B1B0052690A69024F3C95554C0129484C370010196269D071003A079802DE0084E4A53E8CCDC2CA7350ED6549CEC4AC00404D3C30044D1BA78F25EF2CFF28A60084967D9C975003992DF8C240923C45300BE7DAA540E6936194E311802D800D2CB8FC9FA388A84DEFB1CB2CBCBDE9E9C8803A6B00526359F734673F28C367D2DE2F3005256B532D004C40198DF152130803D11211C7550056706E6F3E9D24B0