summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--aoc/datastructures.py8
-rw-r--r--day4/__init__.py72
-rw-r--r--day4/example.txt10
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 -*-
2from abc import ABC
3from typing import Iterator
4
5from aoc import BaseAssignment, I, T
6from aoc.datastructures import Coordinate
7
8
9class 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
39class 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
52class 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@.@.@@@.@.