diff options
| author | 2025-12-04 17:06:44 +0100 | |
|---|---|---|
| committer | 2025-12-04 17:06:44 +0100 | |
| commit | c641dda28310318af8bd0fa6f72a5e1dbc723dac (patch) | |
| tree | 670c9445812ac70e01a3d5edd4ca69c582529515 | |
| parent | 89929901e88749c8428afd0cf5684caa49a246b7 (diff) | |
| download | 2025-c641dda28310318af8bd0fa6f72a5e1dbc723dac.tar.gz 2025-c641dda28310318af8bd0fa6f72a5e1dbc723dac.tar.bz2 2025-c641dda28310318af8bd0fa6f72a5e1dbc723dac.zip | |
Added day4main
| -rw-r--r-- | aoc/datastructures.py | 8 | ||||
| -rw-r--r-- | day4/__init__.py | 72 | ||||
| -rw-r--r-- | day4/example.txt | 10 |
3 files changed, 90 insertions, 0 deletions
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"])): | |||
| 30 | py, | 30 | py, |
| 31 | ) | 31 | ) |
| 32 | 32 | ||
| 33 | def in_bounds(self, field: list[list]) -> bool: | ||
| 34 | return not ( | ||
| 35 | self.x < 0 | ||
| 36 | or self.y < 0 | ||
| 37 | or self.y > len(field) - 1 | ||
| 38 | or self.x > len(field[0]) - 1 | ||
| 39 | ) | ||
| 40 | |||
| 33 | def neighbours(self, no_diagonal: bool = False) -> Iterator["Coordinate"]: | 41 | def neighbours(self, no_diagonal: bool = False) -> Iterator["Coordinate"]: |
| 34 | if no_diagonal: | 42 | if no_diagonal: |
| 35 | yield self + Coordinate(-1, 0) | 43 | 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 @@ | |||
| 1 | # -*- coding: utf-8 -*- | ||
| 2 | from abc import ABC | ||
| 3 | from typing import Iterator | ||
| 4 | |||
| 5 | from aoc import BaseAssignment, I, T | ||
| 6 | from aoc.datastructures import Coordinate | ||
| 7 | |||
| 8 | |||
| 9 | class Assignment(BaseAssignment, ABC): | ||
| 10 | def parse_item(cls, item: str) -> Iterator[list[str]]: | ||
| 11 | yield [c for c in item] | ||
| 12 | |||
| 13 | @classmethod | ||
| 14 | def check_accessible_coordinate( | ||
| 15 | cls, field: list[list[str]], coordinate: Coordinate | ||
| 16 | ) -> bool: | ||
| 17 | neighbouring_roll_count = 0 | ||
| 18 | for neighbor in coordinate.neighbours(): | ||
| 19 | if neighbor.in_bounds(field) and field[neighbor.y][neighbor.x] == "@": | ||
| 20 | neighbouring_roll_count += 1 | ||
| 21 | |||
| 22 | return neighbouring_roll_count < 4 | ||
| 23 | |||
| 24 | @classmethod | ||
| 25 | def get_accessible_coordinates( | ||
| 26 | cls, field: list[list[str]], coordinates: list[Coordinate] | ||
| 27 | ) -> list[Coordinate]: | ||
| 28 | accessible_coordinates = [] | ||
| 29 | for coordinate in coordinates: | ||
| 30 | if field[coordinate.y][coordinate.x] != "@": | ||
| 31 | continue | ||
| 32 | |||
| 33 | if cls.check_accessible_coordinate(field, coordinate): | ||
| 34 | accessible_coordinates.append(coordinate) | ||
| 35 | |||
| 36 | return accessible_coordinates | ||
| 37 | |||
| 38 | |||
| 39 | class AssignmentOne(Assignment): | ||
| 40 | example_result = 13 | ||
| 41 | |||
| 42 | def run(self, input: Iterator[str]) -> int: | ||
| 43 | field = [next(self.parse_item(i)) for i in input] | ||
| 44 | |||
| 45 | coordinates = [ | ||
| 46 | Coordinate(x, y) for y in range(len(field)) for x in range(len(field[y])) | ||
| 47 | ] | ||
| 48 | |||
| 49 | return len(self.get_accessible_coordinates(field, coordinates)) | ||
| 50 | |||
| 51 | |||
| 52 | class AssignmentTwo(Assignment): | ||
| 53 | example_result = 43 | ||
| 54 | |||
| 55 | def run(self, input: Iterator[str]) -> int: | ||
| 56 | field = [next(self.parse_item(i)) for i in input] | ||
| 57 | |||
| 58 | coordinates = [ | ||
| 59 | Coordinate(x, y) for y in range(len(field)) for x in range(len(field[y])) | ||
| 60 | ] | ||
| 61 | |||
| 62 | rolls_removed = 0 | ||
| 63 | while True: | ||
| 64 | accessible_coordinates = self.get_accessible_coordinates(field, coordinates) | ||
| 65 | |||
| 66 | if len(accessible_coordinates) == 0: | ||
| 67 | return rolls_removed | ||
| 68 | |||
| 69 | for coordinate in accessible_coordinates: | ||
| 70 | field[coordinate.y][coordinate.x] = "." | ||
| 71 | |||
| 72 | 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 @@ | |||
| 1 | ..@@.@@@@. | ||
| 2 | @@@.@.@.@@ | ||
| 3 | @@@@@.@.@@ | ||
| 4 | @.@@@@..@. | ||
| 5 | @@.@@@@.@@ | ||
| 6 | .@@@@@@@.@ | ||
| 7 | .@.@.@.@@@ | ||
| 8 | @.@@@.@@@@ | ||
| 9 | .@@@@@@@@. | ||
| 10 | @.@.@@@.@. | ||
