-
Notifications
You must be signed in to change notification settings - Fork 0
/
day_10.py
52 lines (40 loc) · 1.38 KB
/
day_10.py
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
"""
--- Day 10: Pipe Maze ---
"""
from itertools import product
direction_offset = {"N": (-1, 0), "E": (0, 1), "S": (1, 0), "W": (0, -1)}
opposite_direction = {"N": "S", "S": "N", "E": "W", "W": "E"}
pipe_direction = {
"|": ["N", "S"],
"-": ["E", "W"],
"L": ["N", "E"],
"J": ["N", "W"],
"7": ["S", "W"],
"F": ["S", "E"],
"S": ["N", "E", "S", "W"],
}
def in_bounds(row: int, col: int, number_of_rows: int, number_of_columns: int) -> bool:
return 0 <= row < number_of_rows and 0 <= col < number_of_columns
with open("10.in", "r", encoding="utf-8") as f:
pipe_maze = [list(line) for line in f.read().strip().splitlines()]
M, N = len(pipe_maze), len(pipe_maze[0])
start = [(i, j) for i, j in product(range(M), range(N)) if pipe_maze[i][j] == "S"][0]
queue, visited = [start], set()
while queue:
current = queue.pop()
if current in visited:
continue
visited.add(current)
r, c = current
for direction in pipe_direction.get(pipe_maze[r][c], []):
dr, dc = direction_offset[direction]
nr, nc = r + dr, c + dc
if not in_bounds(nr, nc, M, N):
continue
neighbour_pipe = pipe_maze[nr][nc]
can_be_connected = opposite_direction[direction] in pipe_direction.get(
neighbour_pipe, []
)
if can_be_connected:
queue.append(((nr, nc)))
print(len(visited) // 2)