···
2
+
from typing import List, Optional, Tuple
file = '4.input' if len(sys.argv) <= 1 else sys.argv[1]
5
-
grid = list(map(str.strip, open(file).readlines()))
6
+
grid = list(map(list, map(str.strip, open(file).readlines())))
7
-
def check_occupied(y: int, x: int) -> int:
8
+
def check_occupied(y: int, x: int) -> Optional[Tuple[int, int]]:
9
-
return x >= 0 and y >= 0 and grid[y][x] == "@"
10
+
if x >= 0 and y >= 0 and grid[y][x] == "@":
12
+
except IndexError: pass
15
+
def compute_adj(y: int, x: int) -> List[Optional[Tuple[int, int]]]:
17
+
check_occupied(y-1, x-1), check_occupied(y-1, x), check_occupied(y-1, x+1),
18
+
check_occupied(y, x-1), check_occupied(y, x+1),
19
+
check_occupied(y+1, x-1), check_occupied(y+1, x), check_occupied(y+1, x+1)
22
+
def search_removable() -> List[Tuple[int, int]]:
24
+
for y in range(len(grid)):
25
+
for x in range(len(grid[y])):
26
+
if grid[y][x] != "@": continue
27
+
adj = compute_adj(y, x)
28
+
if sum(map(bool, adj)) < 4:
29
+
removable.append((y, x))
13
-
for y in range(len(grid)):
15
-
for x in range(len(row)):
16
-
if row[x] != "@": continue
18
-
check_occupied(y-1, x-1), check_occupied(y-1, x), check_occupied(y-1, x+1),
19
-
check_occupied(y, x-1), check_occupied(y, x+1),
20
-
check_occupied(y+1, x-1), check_occupied(y+1, x), check_occupied(y+1, x+1)
23
-
available_rolls += 1
32
+
removable = search_removable()
33
+
print(f'p1: {len(removable)}')
35
+
while len(removable):
36
+
for (y, x) in removable:
39
+
removable = search_removable()
25
-
print(f'p1: {available_rolls}')
41
+
print(f'p2: {removed_rolls}')