-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path04_printing.py
More file actions
92 lines (71 loc) · 2.68 KB
/
Copy path04_printing.py
File metadata and controls
92 lines (71 loc) · 2.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
from typing import Literal
from utils.data import fetch
ROLL_SYMBOL = "@"
ROLL_THRESHOLD = 4
class Grid:
def __init__(self, grid: list[str]):
_grid = [list(row) for row in grid]
self._starting_grid = [row.copy() for row in _grid]
self._grid = [row.copy() for row in _grid]
self.rows = len(_grid)
self.cols = len(_grid[0])
def _get_surroundings(self, x: int, y: int) -> dict[str, str | None]:
directions = {
"up": (x, y + 1),
"down": (x, y - 1),
"left": (x - 1, y),
"right": (x + 1, y),
"up_left": (x - 1, y + 1),
"up_right": (x + 1, y + 1),
"down_left": (x - 1, y - 1),
"down_right": (x + 1, y - 1),
}
surroundings = {}
for direction, (dx, dy) in directions.items():
surroundings[direction] = self.get_value(dx, dy)
return surroundings
def get_value(self, x: int, y: int) -> str | None:
if y < 0 or y >= self.rows or x < 0 or x >= self.cols:
return None
return self._grid[y][x]
class ToiletGrid(Grid):
def __init__(self, grid: list[str]):
super().__init__(grid)
def is_accessible(self, x: int, y: int) -> bool:
surroundings = self._get_surroundings(x, y)
surrounding_rolls = [
roll for roll in surroundings.values() if roll == ROLL_SYMBOL
]
return len(surrounding_rolls) < ROLL_THRESHOLD
def get_accessible_rolls(self) -> list[tuple[int, int]]:
accessible_rolls = []
for y in range(self.rows):
for x in range(self.cols):
if self.get_value(x, y) == ROLL_SYMBOL and self.is_accessible(x, y):
accessible_rolls.append((x, y))
return accessible_rolls
def _remove_roll(self, x: int, y: int) -> None:
if self.get_value(x, y) == ROLL_SYMBOL:
self._grid[y][x] = "."
def remove_rolls(self, rolls: list[tuple[int, int]]) -> None:
for x, y in rolls:
self._remove_roll(x, y)
def print_grid(self, type: Literal["starting", "grid"] = "grid") -> None:
match type:
case "grid":
for row in self._grid:
print("".join(row))
case _:
for row in self._starting_grid:
print("".join(row))
data = fetch(day=4)
grid = ToiletGrid(data)
max_iteration = 500
removed_rolls = 0
for _ in range(max_iteration):
accessible_rolls = grid.get_accessible_rolls()
if not accessible_rolls:
break
removed_rolls += len(accessible_rolls)
grid.remove_rolls(accessible_rolls)
print(f"Total removed rolls: {removed_rolls}")