From c641dda28310318af8bd0fa6f72a5e1dbc723dac Mon Sep 17 00:00:00 2001 From: Tom van der Lee Date: Thu, 4 Dec 2025 17:06:44 +0100 Subject: Added day4 --- aoc/datastructures.py | 8 ++++++ day4/__init__.py | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++ day4/example.txt | 10 +++++++ 3 files changed, 90 insertions(+) create mode 100644 day4/__init__.py create mode 100644 day4/example.txt diff --git a/aoc/datastructures.py b/aoc/datastructures.py index 1f141e2..9c9594a 100644 --- a/aoc/datastructures.py +++ b/aoc/datastructures.py @@ -30,6 +30,14 @@ class Coordinate(namedtuple("Coordinate", ["x", "y"])): py, ) + def in_bounds(self, field: list[list]) -> bool: + return not ( + self.x < 0 + or self.y < 0 + or self.y > len(field) - 1 + or self.x > len(field[0]) - 1 + ) + def neighbours(self, no_diagonal: bool = False) -> Iterator["Coordinate"]: if no_diagonal: yield self + Coordinate(-1, 0) diff --git a/day4/__init__.py b/day4/__init__.py new file mode 100644 index 0000000..d52d0a1 --- /dev/null +++ b/day4/__init__.py @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- +from abc import ABC +from typing import Iterator + +from aoc import BaseAssignment, I, T +from aoc.datastructures import Coordinate + + +class Assignment(BaseAssignment, ABC): + def parse_item(cls, item: str) -> Iterator[list[str]]: + yield [c for c in item] + + @classmethod + def check_accessible_coordinate( + cls, field: list[list[str]], coordinate: Coordinate + ) -> bool: + neighbouring_roll_count = 0 + for neighbor in coordinate.neighbours(): + if neighbor.in_bounds(field) and field[neighbor.y][neighbor.x] == "@": + neighbouring_roll_count += 1 + + return neighbouring_roll_count < 4 + + @classmethod + def get_accessible_coordinates( + cls, field: list[list[str]], coordinates: list[Coordinate] + ) -> list[Coordinate]: + accessible_coordinates = [] + for coordinate in coordinates: + if field[coordinate.y][coordinate.x] != "@": + continue + + if cls.check_accessible_coordinate(field, coordinate): + accessible_coordinates.append(coordinate) + + return accessible_coordinates + + +class AssignmentOne(Assignment): + example_result = 13 + + def run(self, input: Iterator[str]) -> int: + field = [next(self.parse_item(i)) for i in input] + + coordinates = [ + Coordinate(x, y) for y in range(len(field)) for x in range(len(field[y])) + ] + + return len(self.get_accessible_coordinates(field, coordinates)) + + +class AssignmentTwo(Assignment): + example_result = 43 + + def run(self, input: Iterator[str]) -> int: + field = [next(self.parse_item(i)) for i in input] + + coordinates = [ + Coordinate(x, y) for y in range(len(field)) for x in range(len(field[y])) + ] + + rolls_removed = 0 + while True: + accessible_coordinates = self.get_accessible_coordinates(field, coordinates) + + if len(accessible_coordinates) == 0: + return rolls_removed + + for coordinate in accessible_coordinates: + field[coordinate.y][coordinate.x] = "." + + rolls_removed += len(accessible_coordinates) diff --git a/day4/example.txt b/day4/example.txt new file mode 100644 index 0000000..8209399 --- /dev/null +++ b/day4/example.txt @@ -0,0 +1,10 @@ +..@@.@@@@. +@@@.@.@.@@ +@@@@@.@.@@ +@.@@@@..@. +@@.@@@@.@@ +.@@@@@@@.@ +.@.@.@.@@@ +@.@@@.@@@@ +.@@@@@@@@. +@.@.@@@.@. -- cgit v1.2.3