From 998fc1d2409e60d74d0aefb38630be59ba977eaf Mon Sep 17 00:00:00 2001 From: Tom van der Lee Date: Thu, 30 Jul 2026 20:05:32 +0200 Subject: Added day 5 wip --- day5/__init__.py | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 day5/__init__.py (limited to 'day5/__init__.py') 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 @@ +# -*- coding: utf-8 -*- +from abc import ABC +from typing import Iterator + +from aoc import BaseAssignment, I, T + + +class Assignment(BaseAssignment, ABC): + def parse_item(cls, item: str) -> Iterator[range | None | int]: + try: + [start, end] = item.split("-") + yield range(int(start), int(end) + 1) + except ValueError: + if item == "": + yield None + else: + yield int(item) + + def read_input(self, example=False) -> Iterator[tuple[list[range], list[int]]]: + ranges = [] + ids = [] + + read_ranges = True + for item in super().read_input(example): + if item is None: + read_ranges = False + continue + + if read_ranges: + ranges.append(item) + else: + ids.append(item) + + yield (ranges, ids) + + @classmethod + def find_fresh_ranges_for_id(cls, id: int, ranges: list[range]) -> Iterator[range]: + for r in ranges: + if id in r: + yield r + + +class AssignmentOne(Assignment): + example_result = 3 + + def run(self, input: Iterator[tuple[list[range], list[int]]]) -> T: + ranges, ids = next(input) + + fresh_ids = [] + for id in ids: + if len(list(self.find_fresh_ranges_for_id(id, ranges))) > 0: + fresh_ids.append(id) + + return len(fresh_ids) + + +class AssignmentTwo(Assignment): + example_result = 14 + + @classmethod + def merge_ranges(cls, ranges: list[range]) -> list[range]: + if not ranges: + return [] + + ranges = sorted(ranges, key=lambda r: r.start) + merged = [ranges[0]] + for r in ranges[1:]: + last = merged[-1] + if not (last.stop < r.start): + merged[-1] = range(last.start, max(last.stop, r.stop)) + else: + merged.append(r) + return merged + + def run(self, input: Iterator[tuple[list[range], list[int]]]) -> T: + ranges, ids = next(input) + + fresh_ranges = set() + + for id in ids: + for r in self.find_fresh_ranges_for_id(id, ranges): + fresh_ranges.add(r) + + fresh_ranges = self.merge_ranges(list(fresh_ranges)) + + return sum([r.stop - r.start for r in fresh_ranges]) -- cgit v1.2.3