AoC 2021 D17: Trick Shot
| Problem statement | Source code | Tags: MathematicsPuzzlePhysics
← Previous Back to AoC Index Next →
Part 1
The 2021 me was young and naïve. I knew I shouldn't simulate the trajectory, but my math was more complex than necessary. Here was my initial idea: for each , subsequent y positions are given by . We want to find the largest such that has a solution for some positive integer .
However, there's a much simpler approach. The probe's y velocity starts at and decreases by 1 each step. If the highest point is , then at height in ascent, it has y velocity . At height , it has y velocity then . At height in descent, it has y velocity . When the probe returns to y=0, due to symmetry, its velocity is . The next step, it will be at . Since the target area is below y=0, we need , or . The maximum initial y velocity is thus , and the height is given by .
Ideally, we should verify that the (which is unique) at which the probe reaches the target y range also admits an integer solution for x. I didn't do this, because I assumed that if is sufficiently large, there would always be a solution for x since the x velocity decreases to 0 and remains there.
Part 2
Part 1 gave the maximum initial y velocity. The minimum initial y velocity is if you shoot down, in which case the y position after 1 step is , and we need . So the range of initial y velocities is .
For x, the maximum initial x velocity is if you shoot directly to the right, in which case the x position after 1 step is , and we need . The minimum initial x velocity is trickier. If the initial x velocity is , then after steps, the probe will have traveled and can't move any farther. We want , which is . Thus, .
There are only more than 30,000 possible initial velocity pairs in this range, so we can brute-force test each pair. (Note that binary search would not work here since the valid velocities do not form a contiguous range.) For each one, the simple way is to run the simulation, which would only take 20-something iterations. However, I decided to flex some more math to determine whether a given initial velocity will hit the target area, and if so, when. I'm not even sure if this is more efficient since now we have floating point arithmetic, but it was fun.
Recall that for y position, we want . Rearranging:
for both inequalities. Since , both discriminants are positive. Both parabolas open upwards and intersect the t-axis twice, with the one above, or inside, the one. If we label the four intersection points left-to-right as , , , , then we want the ranges and .
One of these ranges is:
The other range has the minus sign in front of the square roots, which makes the range negative because and are negative, so we discard it.
The x position is more complicated, because it has two pieces. The first piece is the same as y: . The second piece is when , in which case the x position is . We now solve for . If is a valid solution, then any is also valid. Focusing on the first piece, we have:
Which only holds for , which is the left half. This time the determinant may be negative. If , then there are no solutions because neither parabola intersects the t-axis. If , then the parabola does not intersect the t-axis so is always a valid solution, and any is also valid, so the solution range is . If both discriminants are positive, then the valid range is , or if . Coding this up:
This allows us to find the valid t ranges for each and in constant time. Finally we just need to check if the two t ranges overlap.