diff options
| author | 2026-07-30 20:05:32 +0200 | |
|---|---|---|
| committer | 2026-07-30 20:05:43 +0200 | |
| commit | 998fc1d2409e60d74d0aefb38630be59ba977eaf (patch) | |
| tree | eed246cf5af3fa8b85bf845622ddea8568b8fdbb | |
| parent | c641dda28310318af8bd0fa6f72a5e1dbc723dac (diff) | |
| download | 2025-998fc1d2409e60d74d0aefb38630be59ba977eaf.tar.gz 2025-998fc1d2409e60d74d0aefb38630be59ba977eaf.tar.bz2 2025-998fc1d2409e60d74d0aefb38630be59ba977eaf.zip | |
Added day 5 wipmain
| -rw-r--r-- | day5/__init__.py | 86 | ||||
| -rw-r--r-- | day5/example.txt | 11 | ||||
| -rw-r--r-- | day5/test_init.py | 23 |
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 -*- | ||
| 2 | from abc import ABC | ||
| 3 | from typing import Iterator | ||
| 4 | |||
| 5 | from aoc import BaseAssignment, I, T | ||
| 6 | |||
| 7 | |||
| 8 | class 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 | |||
| 43 | class 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 | |||
| 57 | class 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 @@ | |||
| 1 | 3-5 | ||
| 2 | 10-14 | ||
| 3 | 16-20 | ||
| 4 | 12-18 | ||
| 5 | |||
| 6 | 1 | ||
| 7 | 5 | ||
| 8 | 8 | ||
| 9 | 11 | ||
| 10 | 17 | ||
| 11 | 32 | ||
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 -*- | ||
| 2 | from unittest import result | ||
| 3 | |||
| 4 | import pytest | ||
| 5 | |||
| 6 | from day5 import AssignmentTwo | ||
| 7 | |||
| 8 | |||
| 9 | class 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 | ||
