-
Notifications
You must be signed in to change notification settings - Fork 4
/
main.py
54 lines (45 loc) · 1.78 KB
/
main.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
import numpy as np
from more_itertools import flatten
from more_itertools import pairwise
from PIL import Image, ImageOps
from skimage.draw import line as draw_line
with open("input.txt") as f:
lines = [[[int(c) for c in k.split(",")] for k in l.split(" -> ")] for l in f]
min_x, min_y = min([x for x, _ in flatten(lines)]+[500]), min([y for _, y in flatten(lines)]+[0])
max_x, max_y = max([x for x, _ in flatten(lines)]+[500]), max([y for _, y in flatten(lines)]+[0])
dim_x, dim_y = (max_x - min_x)+1, (max_y - min_y)+3
grid = np.zeros((dim_y, dim_x), dtype="uint8")
for line in lines:
for a, b in pairwise(line):
rr, cc = draw_line(a[1]-min_y, a[0]-min_x, b[1]-min_y, b[0]-min_x)
grid[rr, cc] = 1
add_border = 300
grid = np.array(ImageOps.expand(Image.fromarray(grid), border=(add_border,0,add_border,0), fill=0))
rr, cc = draw_line(dim_y-1, 0, dim_y-1, dim_x-1+add_border*2)
grid[rr, cc] = 1
offset_x, offset_y = add_border, 0
generate_new_sand = True
init_pos_y, init_pos_x = 0-min_y+offset_y, 500-min_x+offset_x
try:
while True:
if generate_new_sand:
if grid[init_pos_y, init_pos_x] == 3:
break
grid[init_pos_y, init_pos_x] = 2
pos_y, pos_x = init_pos_y, init_pos_x
generate_new_sand = False
else:
pos_y, pos_x = new_pos_y, new_pos_x
for new_pos_y, new_pos_x in [(pos_y+1, pos_x), (pos_y+1, pos_x-1), (pos_y+1, pos_x+1)]:
# if new_pos_x == -1:
# raise Exception()
if grid[new_pos_y, new_pos_x] == 0:
grid[pos_y, pos_x] = 0
grid[new_pos_y, new_pos_x] = 2
break
else:
grid[pos_y, pos_x] = 3
generate_new_sand = True
except:
pass
print(np.sum([grid == 3]))