diff options
Diffstat (limited to 'day4')
| -rw-r--r-- | day4/__init__.py | 72 | ||||
| -rw-r--r-- | day4/example.txt | 10 |
2 files changed, 82 insertions, 0 deletions
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 | @.@.@@@.@. | ||
