summaryrefslogtreecommitdiffstats
path: root/day5/__init__.py
diff options
context:
space:
mode:
authorGravatar Tom van der Lee <tom@vanderlee.io>2026-07-30 20:05:32 +0200
committerGravatar Tom van der Lee <tom@vanderlee.io>2026-07-30 20:05:43 +0200
commit998fc1d2409e60d74d0aefb38630be59ba977eaf (patch)
treeeed246cf5af3fa8b85bf845622ddea8568b8fdbb /day5/__init__.py
parentc641dda28310318af8bd0fa6f72a5e1dbc723dac (diff)
download2025-main.tar.gz
2025-main.tar.bz2
2025-main.zip
Added day 5 wipmain
Diffstat (limited to 'day5/__init__.py')
-rw-r--r--day5/__init__.py86
1 files changed, 86 insertions, 0 deletions
diff --git a/day5/__init__.py b/day5/__init__.py
new file mode 100644
index 0000000..399aedc
--- /dev/null
+++ b/day5/__init__.py
@@ -0,0 +1,86 @@
1# -*- coding: utf-8 -*-
2from abc import ABC
3from typing import Iterator
4
5from aoc import BaseAssignment, I, T
6
7
8class Assignment(BaseAssignment, ABC):
9 def parse_item(cls, item: str) -> Iterator[range | None | int]:
10 try:
11 [start, end] = item.split("-")
12 yield range(int(start), int(end) + 1)
13 except ValueError:
14 if item == "":
15 yield None
16 else:
17 yield int(item)
18
19 def read_input(self, example=False) -> Iterator[tuple[list[range], list[int]]]:
20 ranges = []
21 ids = []
22
23 read_ranges = True
24 for item in super().read_input(example):
25 if item is None:
26 read_ranges = False
27 continue
28
29 if read_ranges:
30 ranges.append(item)
31 else:
32 ids.append(item)
33
34 yield (ranges, ids)
35
36 @classmethod
37 def find_fresh_ranges_for_id(cls, id: int, ranges: list[range]) -> Iterator[range]:
38 for r in ranges:
39 if id in r:
40 yield r
41
42
43class AssignmentOne(Assignment):
44 example_result = 3
45
46 def run(self, input: Iterator[tuple[list[range], list[int]]]) -> T:
47 ranges, ids = next(input)
48
49 fresh_ids = []
50 for id in ids:
51 if len(list(self.find_fresh_ranges_for_id(id, ranges))) > 0:
52 fresh_ids.append(id)
53
54 return len(fresh_ids)
55
56
57class AssignmentTwo(Assignment):
58 example_result = 14
59
60 @classmethod
61 def merge_ranges(cls, ranges: list[range]) -> list[range]:
62 if not ranges:
63 return []
64
65 ranges = sorted(ranges, key=lambda r: r.start)
66 merged = [ranges[0]]
67 for r in ranges[1:]:
68 last = merged[-1]
69 if not (last.stop < r.start):
70 merged[-1] = range(last.start, max(last.stop, r.stop))
71 else:
72 merged.append(r)
73 return merged
74
75 def run(self, input: Iterator[tuple[list[range], list[int]]]) -> T:
76 ranges, ids = next(input)
77
78 fresh_ranges = set()
79
80 for id in ids:
81 for r in self.find_fresh_ranges_for_id(id, ranges):
82 fresh_ranges.add(r)
83
84 fresh_ranges = self.merge_ranges(list(fresh_ranges))
85
86 return sum([r.stop - r.start for r in fresh_ranges])