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)