Add 2021-16 in Python
Signed-off-by: AKU <tom@tdpain.net>
This commit is contained in:
parent
47c497080e
commit
736c040328
6 changed files with 234 additions and 0 deletions
15
challenges/2021/15-chiton/benchmark.json
Normal file
15
challenges/2021/15-chiton/benchmark.json
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"day": 15,
|
||||
"dir": "challenges/2021/15-chiton",
|
||||
"implementations": {
|
||||
"Python": {
|
||||
"part.1.avg": 0.05848939180374146,
|
||||
"part.1.max": 0.22109389305114746,
|
||||
"part.1.min": 0.03475213050842285,
|
||||
"part.2.avg": 0.00003055143356323242,
|
||||
"part.2.max": 0.0002415180206298828,
|
||||
"part.2.min": 0.000008344650268554688
|
||||
}
|
||||
},
|
||||
"numRuns": 1000
|
||||
}
|
2
challenges/2021/16-packetDecoder/README.md
Normal file
2
challenges/2021/16-packetDecoder/README.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
# [Day 16: Packet Decoder](https://adventofcode.com/2021/day/16)
|
||||
|
15
challenges/2021/16-packetDecoder/benchmark.json
Normal file
15
challenges/2021/16-packetDecoder/benchmark.json
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"day": 16,
|
||||
"dir": "challenges/2021/16-packetDecoder",
|
||||
"implementations": {
|
||||
"Python": {
|
||||
"part.1.avg": 0.002915963888168335,
|
||||
"part.1.max": 0.011673688888549805,
|
||||
"part.1.min": 0.0016696453094482422,
|
||||
"part.2.avg": 0.0029851856231689453,
|
||||
"part.2.max": 0.019982337951660156,
|
||||
"part.2.min": 0.0017099380493164062
|
||||
}
|
||||
},
|
||||
"numRuns": 1000
|
||||
}
|
57
challenges/2021/16-packetDecoder/info.json
Normal file
57
challenges/2021/16-packetDecoder/info.json
Normal file
|
@ -0,0 +1,57 @@
|
|||
{
|
||||
"inputFile": "input.txt",
|
||||
"testCases": {
|
||||
"one": [
|
||||
{
|
||||
"input": "8A004A801A8002F478",
|
||||
"expected": "16"
|
||||
},
|
||||
{
|
||||
"input": "620080001611562C8802118E34",
|
||||
"expected": "12"
|
||||
},
|
||||
{
|
||||
"input": "C0015000016115A2E0802F182340",
|
||||
"expected": "23"
|
||||
},
|
||||
{
|
||||
"input": "A0016C880162017C3686B18A3D4780",
|
||||
"expected": "31"
|
||||
}
|
||||
],
|
||||
"two": [
|
||||
{
|
||||
"input": "C200B40A82",
|
||||
"expected": "3"
|
||||
},
|
||||
{
|
||||
"input": "04005AC33890",
|
||||
"expected": "54"
|
||||
},
|
||||
{
|
||||
"input": "880086C3E88112",
|
||||
"expected": "7"
|
||||
},
|
||||
{
|
||||
"input": "CE00C43D881120",
|
||||
"expected": "9"
|
||||
},
|
||||
{
|
||||
"input": "D8005AC2A8F0",
|
||||
"expected": "1"
|
||||
},
|
||||
{
|
||||
"input": "F600BC2D8F",
|
||||
"expected": "0"
|
||||
},
|
||||
{
|
||||
"input": "9C005AC2F8F0",
|
||||
"expected": "0"
|
||||
},
|
||||
{
|
||||
"input": "9C0141080250320F1802104A08",
|
||||
"expected": "1"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
144
challenges/2021/16-packetDecoder/py/__init__.py
Normal file
144
challenges/2021/16-packetDecoder/py/__init__.py
Normal file
|
@ -0,0 +1,144 @@
|
|||
from dataclasses import dataclass
|
||||
from typing import Any, List, SupportsIndex
|
||||
from aocpy import BaseChallenge
|
||||
|
||||
|
||||
class Consumer:
|
||||
def __init__(self, instr: str):
|
||||
self.input = instr
|
||||
self.pointer = 0
|
||||
|
||||
def get(self) -> str:
|
||||
return self.get_n(1)
|
||||
|
||||
def get_n(self, n) -> str:
|
||||
self.pointer += n
|
||||
if self.pointer > len(self.input):
|
||||
raise IndexError("index out of bounds")
|
||||
return self.input[self.pointer-n:self.pointer]
|
||||
|
||||
def finished(self) -> bool:
|
||||
return len(self.input) == self.pointer
|
||||
|
||||
@dataclass
|
||||
class Packet:
|
||||
version: int
|
||||
type_indicator: int
|
||||
content: Any
|
||||
|
||||
def hex_to_binary_string(n: str) -> str:
|
||||
o = ""
|
||||
for char in n:
|
||||
o += bin(int(char, base=16))[2:].zfill(4)
|
||||
return o
|
||||
|
||||
def from_binary_string(x: str) -> int:
|
||||
return int(x, base=2)
|
||||
|
||||
def decode_all(input_stream: Consumer) -> List[Packet]:
|
||||
o = []
|
||||
while True:
|
||||
try:
|
||||
o.append(decode_one(input_stream))
|
||||
except IndexError:
|
||||
break
|
||||
return o
|
||||
|
||||
def decode_one(input_stream: Consumer) -> Packet:
|
||||
version = from_binary_string(input_stream.get_n(3))
|
||||
packet_type = from_binary_string(input_stream.get_n(3))
|
||||
|
||||
if packet_type == 4:
|
||||
literal_number = 0
|
||||
while True:
|
||||
continue_bit = from_binary_string(input_stream.get())
|
||||
literal_number = (literal_number << 4) | from_binary_string(input_stream.get_n(4))
|
||||
if continue_bit == 0:
|
||||
break
|
||||
return Packet(version, packet_type, literal_number)
|
||||
else:
|
||||
length_type = from_binary_string(input_stream.get())
|
||||
if length_type == 0:
|
||||
# 15 bit subpackt length indicator
|
||||
run_length = from_binary_string(input_stream.get_n(15))
|
||||
content = decode_all(Consumer(input_stream.get_n(run_length)))
|
||||
return Packet(version, packet_type, content)
|
||||
else:
|
||||
# 11 bit subpacket count
|
||||
subpacket_count = from_binary_string(input_stream.get_n(11))
|
||||
content = []
|
||||
for _ in range(subpacket_count):
|
||||
content.append(decode_one(input_stream))
|
||||
return Packet(version, packet_type, content)
|
||||
|
||||
|
||||
def parse(instr: str) -> List[Packet]:
|
||||
return decode_all(Consumer(hex_to_binary_string(instr.strip())))
|
||||
|
||||
|
||||
def sum_version_numbers(packets: List[Packet]) -> int:
|
||||
sigma = 0
|
||||
for packet in packets:
|
||||
sigma += packet.version
|
||||
if type(packet.content) == list:
|
||||
sigma += sum_version_numbers(packet.content)
|
||||
return sigma
|
||||
|
||||
|
||||
def interpet_packet(packet: Packet) -> int:
|
||||
if packet.type_indicator == 0:
|
||||
# sum packet
|
||||
sigma = 0
|
||||
for subpacket in packet.content:
|
||||
sigma += interpet_packet(subpacket)
|
||||
return sigma
|
||||
elif packet.type_indicator == 1:
|
||||
# product packet
|
||||
product = 1
|
||||
for subpacket in packet.content:
|
||||
product *= interpet_packet(subpacket)
|
||||
return product
|
||||
elif packet.type_indicator == 2:
|
||||
# min packet
|
||||
vals = []
|
||||
for subpacket in packet.content:
|
||||
vals.append(interpet_packet(subpacket))
|
||||
return min(vals)
|
||||
elif packet.type_indicator == 3:
|
||||
# max packet
|
||||
vals = []
|
||||
for subpacket in packet.content:
|
||||
vals.append(interpet_packet(subpacket))
|
||||
return max(vals)
|
||||
elif packet.type_indicator == 4:
|
||||
return packet.content
|
||||
elif packet.type_indicator == 5:
|
||||
# greater than packet
|
||||
first = interpet_packet(packet.content[0])
|
||||
second = interpet_packet(packet.content[1])
|
||||
return 1 if first > second else 0
|
||||
elif packet.type_indicator == 6:
|
||||
# less than packet
|
||||
first = interpet_packet(packet.content[0])
|
||||
second = interpet_packet(packet.content[1])
|
||||
return 1 if first < second else 0
|
||||
elif packet.type_indicator == 7:
|
||||
# equal to packet
|
||||
first = interpet_packet(packet.content[0])
|
||||
second = interpet_packet(packet.content[1])
|
||||
return 1 if first == second else 0
|
||||
else:
|
||||
raise ValueError(f"unknown packet type {packet.type_indicator}")
|
||||
|
||||
|
||||
class Challenge(BaseChallenge):
|
||||
|
||||
@staticmethod
|
||||
def one(instr: str) -> int:
|
||||
packets = parse(instr)
|
||||
return sum_version_numbers(packets)
|
||||
|
||||
@staticmethod
|
||||
def two(instr: str) -> int:
|
||||
packets = parse(instr)
|
||||
return interpet_packet(packets[0])
|
|
@ -27,6 +27,7 @@ Solutions to the [2021 Advent of Code](https://adventofcode.com/2021).
|
|||
| 13 - Transparent Origami | ★ ★ | [Python](13-transparentOrigami/py), [Nim](13-transparentOrigami/nim) | I got stuck for hours on an intermittent off-by-one error. :( |
|
||||
| 14 - Extended Polymerization | ★ ★ | [Python](14-extendedPolymerization/py) | Another off-by-one error, but this time it was because of dodgy division. Wonderful. |
|
||||
| 15 - Chiton | ★ ☆ | [Python](15-chiton/py) | Pathfinding is hard |
|
||||
| 16 - Packet Decoder | ★ ★ | [Python](16-packetDecoder/py) | Parsing and interpreting stuff is surprisingly enjoyable |
|
||||
|
||||
<!-- PARSE END -->
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue