-
Notifications
You must be signed in to change notification settings - Fork 0
/
day_16.py
92 lines (70 loc) · 2.9 KB
/
day_16.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
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
"""
--- Day 16: The Floor Will Be Lava ---
"""
from pprint import pprint
EMPTY_SPACE = "."
VERTICAL_SPLITTER, HORIZONTAL_SPLITTER = "|", "-"
BEAM_START = 0, 0
DIRECTIONS = {"UP": (-1, 0), "LEFT": (0, -1), "DOWN": (1, 0), "RIGHT": (0, 1)}
def in_bounds(r: int, c: int, number_of_rows: int, number_of_columns: int) -> bool:
return 0 <= r < number_of_rows and 0 <= c < number_of_columns
with open("16-test.in", "r", encoding="utf-8") as f:
test_grid = [list(line) for line in f.read().strip().split()]
R, C = len(test_grid), len(test_grid[0])
current_beams, energized = [(BEAM_START, (0, 1))], set()
while current_beams:
position, direction = current_beams.pop()
x, y = position
if not in_bounds(x, y, R, C):
continue
energized.add((x, y))
dx, dy = direction
nx, ny = x + dx, y + dy
if not in_bounds(nx, ny, R, C):
continue
if test_grid[nx][ny] == EMPTY_SPACE:
current_beams.append(((nx, ny), direction))
elif test_grid[nx][ny] == "/":
energized.add((nx, ny))
if direction == DIRECTIONS["UP"]:
new_direction = DIRECTIONS["RIGHT"]
elif direction == DIRECTIONS["LEFT"]:
new_direction = DIRECTIONS["DOWN"]
elif direction == DIRECTIONS["DOWN"]:
new_direction = DIRECTIONS["LEFT"]
elif direction == DIRECTIONS["RIGHT"]:
new_direction = DIRECTIONS["UP"]
dnx, dny = new_direction
current_beams.append(((nx + dnx, ny + dny), new_direction))
elif test_grid[nx][ny] == "\\":
energized.add((nx, ny))
if direction == DIRECTIONS["UP"]:
new_direction = DIRECTIONS["LEFT"]
elif direction == DIRECTIONS["LEFT"]:
new_direction = DIRECTIONS["UP"]
elif direction == DIRECTIONS["DOWN"]:
new_direction = DIRECTIONS["RIGHT"]
elif direction == DIRECTIONS["RIGHT"]:
new_direction = DIRECTIONS["DOWN"]
dnx, dny = new_direction
current_beams.append(((nx + dnx, ny + dny), new_direction))
elif test_grid[nx][ny] == VERTICAL_SPLITTER:
energized.add((nx, ny))
if direction in (DIRECTIONS["UP"], DIRECTIONS["DOWN"]):
current_beams.append(((nx + dx, ny + dy), direction))
continue
current_beams.append(((nx - 1, ny), DIRECTIONS["UP"]))
current_beams.append(((nx + 1, ny), DIRECTIONS["DOWN"]))
elif test_grid[nx][ny] == HORIZONTAL_SPLITTER:
energized.add((nx, ny))
if direction in (DIRECTIONS["LEFT"], DIRECTIONS["RIGHT"]):
current_beams.append(((nx + dx, ny + dy), direction))
continue
current_beams.append(((nx, ny + 1), DIRECTIONS["RIGHT"]))
current_beams.append(((nx, ny - 1), DIRECTIONS["LEFT"]))
print(len(energized))
# print energized map
energized_map = [["." for _ in range(C)] for _ in range(R)]
for r, c in energized:
energized_map[r][c] = "#"
pprint(energized_map)