Skip to content

Commit 3568e3c

Browse files
committed
Day 14
1 parent 2cd9635 commit 3568e3c

File tree

6 files changed

+330
-1
lines changed

6 files changed

+330
-1
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
__pycache__
22
.sessioncookie
33

4-
venv
4+
venv
5+
.DS_Store

2022/14/input.txt

+182
Large diffs are not rendered by default.

2022/14/regolith_reservoir.py

+146
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
import numpy as np
2+
import matplotlib.pyplot as plt
3+
from matplotlib import animation
4+
from utils import read_input, run, sliding_window
5+
6+
7+
FNAME = "14/input.txt"
8+
WALL = 1
9+
SAND = 2
10+
11+
def parse_chunk(line):
12+
return [tuple(map(int, coord.split(','))) for coord in line.split(' -> ')]
13+
14+
15+
##########
16+
# PART 1 #
17+
##########
18+
19+
20+
def line_points(start, end):
21+
x1, y1 = start
22+
x2, y2 = end
23+
if x1 == x2:
24+
return [(x1, y) for y in range(min(y1, y2), max(y1, y2) + 1)]
25+
elif y1 == y2:
26+
return [(x, y1) for x in range(min(x1, x2), max(x1, x2) + 1)]
27+
28+
29+
def build_grid(lines):
30+
max_y = max(y for l in lines for _, y in l) + 3
31+
grid = np.zeros((1001, max_y))
32+
33+
for line in lines:
34+
for start, end in sliding_window(line, 2):
35+
for point in line_points(start, end):
36+
grid[point] = WALL
37+
38+
return grid
39+
40+
41+
def try_move(grid, sand):
42+
x, y = sand
43+
next_y = y + 1
44+
if x == 0:
45+
raise Exception(f'{sand}')
46+
if not grid[(x, next_y)]:
47+
return (x, next_y)
48+
if not grid[(x-1, next_y)]:
49+
return (x-1, next_y)
50+
if not grid[(x+1, next_y)]:
51+
return (x+1, next_y)
52+
53+
return sand
54+
55+
56+
def simulate_sand(grid):
57+
current = (500, 0)
58+
if grid[current]:
59+
return False # Full
60+
61+
while True:
62+
next_position = try_move(grid, current)
63+
if next_position == current:
64+
grid[current] = SAND
65+
return True # Landed
66+
67+
if next_position[1] == grid.shape[1] - 1:
68+
return False # Abyss
69+
70+
current = next_position
71+
72+
73+
def part_one(input_file):
74+
grid = build_grid(read_input(input_file, parse_chunk=parse_chunk))
75+
76+
landed = 0
77+
while simulate_sand(grid):
78+
landed += 1
79+
80+
# def next_grid():
81+
# simulate_sand(grid)
82+
# return grid
83+
84+
# show(grid, frames=862, next_grid=next_grid)
85+
86+
return landed
87+
88+
89+
90+
91+
##########
92+
# PART 2 #
93+
##########
94+
95+
96+
def part_two(input_file):
97+
grid = build_grid(read_input(input_file, parse_chunk=parse_chunk))
98+
grid[:, grid.shape[1] - 1] = WALL
99+
100+
landed = 0
101+
while simulate_sand(grid):
102+
landed += 1
103+
104+
# def next_grid():
105+
# for i in range(30):
106+
# simulate_sand(grid)
107+
# return grid
108+
109+
# show(grid, frames=925, next_grid=next_grid)
110+
111+
return landed
112+
113+
114+
def show(grid, frames, next_grid):
115+
def format(grid):
116+
return grid.T[:,350:650]
117+
118+
fig = plt.figure()
119+
im = plt.imshow(format(grid), animated=True, cmap='viridis', vmin=0, vmax=2)
120+
plt.tight_layout()
121+
plt.grid(False)
122+
plt.axis('off')
123+
124+
def init():
125+
im.set_data(format(grid))
126+
return im,
127+
128+
def animate(i):
129+
im.set_array(format(next_grid()))
130+
return im,
131+
132+
anim = animation.FuncAnimation(
133+
fig,
134+
animate,
135+
init_func=init,
136+
frames=frames,
137+
interval=1,
138+
blit=True,
139+
)
140+
141+
anim.save(f"sand_{frames}.gif")
142+
plt.show()
143+
144+
145+
if __name__ == '__main__':
146+
run(part_one, part_two, FNAME)

2022/14/sand_2875.gif

6.23 MB
Loading

2022/14/sand_862.gif

672 KB
Loading

2022/14/sand_925.gif

2.63 MB
Loading

0 commit comments

Comments
 (0)