summaryrefslogtreecommitdiffstats
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
parentc641dda28310318af8bd0fa6f72a5e1dbc723dac (diff)
download2025-main.tar.gz
2025-main.tar.bz2
2025-main.zip
Added day 5 wipmain
-rw-r--r--day5/__init__.py86
-rw-r--r--day5/example.txt11
-rw-r--r--day5/test_init.py23
3 files changed, 120 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])
diff --git a/day5/example.txt b/day5/example.txt
new file mode 100644
index 0000000..2e9078d
--- /dev/null
+++ b/day5/example.txt
@@ -0,0 +1,11 @@
13-5
210-14
316-20
412-18
5
61
75
88
911
1017
1132
diff --git a/day5/test_init.py b/day5/test_init.py
new file mode 100644
index 0000000..018387b
--- /dev/null
+++ b/day5/test_init.py
@@ -0,0 +1,23 @@
1# -*- coding: utf-8 -*-
2from unittest import result
3
4import pytest
5
6from day5 import AssignmentTwo
7
8
9class TestAssignmentTwo:
10 data = [
11 [
12 [range(3, 6), range(10, 15), range(16, 21), range(12, 19)],
13 [range(3, 6), range(10, 21)],
14 ],
15 [[range(2, 8), range(4, 6)], [range(2, 8)]],
16 [[range(4, 6), range(2, 8)], [range(2, 8)]],
17 [[range(1, 3), range(3, 6)], [range(1, 6)]],
18 [[range(3, 6), range(1, 3)], [range(1, 6)]],
19 ]
20
21 @pytest.mark.parametrize("ranges,result", data)
22 def test_merge_ranges(self, ranges: list[range], result: list[range]):
23 assert AssignmentTwo.merge_ranges(ranges) == result