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