1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
# -*- coding: utf-8 -*-
import json
from abc import ABC
from functools import cmp_to_key, reduce
from typing import Iterator, Any, List, Tuple, Union
from aoc import BaseAssignment
Packet = Union[List[int], int, List["Packet"]]
class Assignment(BaseAssignment, ABC):
def compare_pair(self, pair: Tuple[Packet, Packet]):
packet_a, packet_b = pair
if isinstance(packet_a, int) and isinstance(packet_b, int):
diff = packet_b - packet_a
return diff / abs(diff) if diff != 0 else 0
if isinstance(packet_a, list) and isinstance(packet_b, int):
packet_b = [packet_b]
if isinstance(packet_b, list) and isinstance(packet_a, int):
packet_a = [packet_a]
try:
for sub_pair in zip(packet_a, packet_b, strict=True):
comparison = self.compare_pair(sub_pair)
if comparison != 0:
return comparison
except ValueError:
return self.compare_pair((len(packet_a), len(packet_b)))
return 0
class AssignmentOne(Assignment):
example_result = 13
def pairs(self, input: Iterator[str]):
while True:
yield (json.loads(next(input)), json.loads(next(input)))
try:
next(input)
except StopIteration:
break
def run(self, input: Iterator) -> Any:
return sum(
index
for index, pair in enumerate(self.pairs(input), start=1)
if self.compare_pair(pair) > 0
)
class AssignmentTwo(Assignment):
example_result = 140
def packets(self, input: Iterator[str]):
for item in input:
if item == "":
continue
yield json.loads(item)
def run(self, input: Iterator) -> Any:
packets = sorted(
[[[2]], [[6]], *self.packets(input)],
key=cmp_to_key(lambda a, b: self.compare_pair((a, b))),
reverse=True,
)
return reduce(
lambda o, i: o * i,
[
index
for index, packet in enumerate(packets, start=1)
if packet
in (
[[2]],
[[6]],
)
],
)
|