-
Notifications
You must be signed in to change notification settings - Fork 17
/
day14.py
executable file
·95 lines (70 loc) · 1.29 KB
/
day14.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
93
94
95
#!/usr/bin/env python3
from utils.all import *
advent.setup(2022, 14)
fin = advent.get_input()
intmat = read_int_matrix(fin); fin.seek(0, 0)
ans = 0
rock = set()
sand = set()
def dump():
res = ''
for y in range(13):
for x in range(490, 510):
if (x, y) in rock:
res += '#'
elif (x, y) in sand:
res += 'o'
else:
res += '.'
res += '\n'
eprint(res)
for line in intmat:
px, py = None, None
for x, y in [line[i:i + 2] for i in range(0, len(line), 2)]:
if px is None:
px, py = x, y
continue
if y == py:
for i in autorange(x, px):
rock.add((i, y))
elif x == px:
for i in autorange(y, py):
rock.add((x, i))
else:
assert False
px, py = x, y
floory = max(map(itemgetter(1), rock)) + 2
def occ(p):
return p in rock or p in sand or p[1] == floory
def pour(part2=False):
x = 500
y = 0
p = x, y
if part2 and occ(p):
return True
while 1:
x, y = p
if not occ((x, y + 1)):
p = (x, y + 1)
continue
l = (x - 1, y + 1)
r = (x + 1, y + 1)
if not occ(l):
p = l
continue
if not occ(r):
p = r
continue
break
if not part2 and p[1] + 1 == floory:
return True
sand.add(p)
return False
while not pour():
ans += 1
# dump()
advent.print_answer(1, ans)
while not pour(True):
ans += 1
# dump()
advent.print_answer(2, ans)