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
|
from math import sqrt, ceil, floor
from utils import parse_day
tx_min, tx_max, ty_min, ty_max = \
map(int, parse_day(17, r'.* x=(-?\d+)..(-?\d+), y=(-?\d+)..(-?\d+)'))
vx_min = int(sqrt(tx_min * 2) - 1)
vx_max = tx_max
vy_min = ty_min
vy_max = abs(ty_min) - 1
def sum_n(n):
return n * (n + 1) // 2
print(sum_n(vy_max))
def time_at_pos(v, d):
"""d = - (t + 1)(t - 2v) / 2 solved for t"""
return (sqrt((2 * v + 1) ** 2 - 8 * d) + 2 * v - 1) / 2 + 1
def y_times(vy0):
start = time_at_pos(vy0, ty_max)
end = time_at_pos(vy0, ty_min)
return range(ceil(start), floor(end) + 1)
def x_at(vx0, t):
assert(t >= 0)
return sum_n(vx0) - sum_n(max(vx0 - t, 0))
count = 0
for vy0 in range(vy_min, vy_max + 1):
for vx0 in range(vx_min, vx_max + 1):
for t in y_times(vy0):
if tx_min <= x_at(vx0, t) <= tx_max:
count += 1
break
print(count)
|