-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathday17.py
executable file
·54 lines (38 loc) · 1.15 KB
/
day17.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
#!/usr/bin/env python3
import sys
import re
def invtri(x):
return int((x * 2)**0.5)
def search(xmin, xmax, ymin, ymax, v0xmin):
total = 0
yhi = 0
for v0x in range(v0xmin, xmax + 1):
for v0y in range(ymin, -ymin):
x, y = 0, 0
vx, vy = v0x, v0y
while x <= xmax and y >= ymin:
if x >= xmin and y <= ymax:
total += 1
break
x, y = (x + vx, y + vy)
vy -= 1
if vx > 0:
vx -= 1
if y > yhi:
yhi = y
return yhi, total
# Open the first argument as input or use stdin if no arguments were given
fin = open(sys.argv[1]) if len(sys.argv) > 1 else sys.stdin
xmin, xmax, ymin, ymax = map(int, re.findall(r'-?\d+', fin.read()))
assert ymin < 0 and ymax < 0
v0xmin = invtri(xmin)
# Here, if the following assumption holds (tri(n) == n-th triangular number):
#
# assert tri(v0xmin) == xmin or tri(v0xmin + 1) <= xmax
#
# we could simply calculate yhi = tri(ymin) = ymin * (ymin + 1) // 2. To be
# safer though, and since we need to do a brute-force for P2 anyway, I have also
# integrated P1's calculation into search().
yhi, total = search(xmin, xmax, ymin, ymax, v0xmin)
print('Part 1:', yhi)
print('Part 2:', total)