This topic is about Day 17 of the Advent of Code 2021.
We have a private leaderboard (shared with users of Erlang Forums):
https://adventofcode.com/2021/leaderboard/private/view/370884
The entry code is:
370884-a6a71927
This topic is about Day 17 of the Advent of Code 2021.
We have a private leaderboard (shared with users of Erlang Forums):
https://adventofcode.com/2021/leaderboard/private/view/370884
The entry code is:
370884-a6a71927
I used a brute-force solution, testing many more initial velocities than necessary. It does the job in less than 3 seconds on my computer.
I think for part1, to find the best initial y
velocity we can use something like y = abs(target_area.y.min) - 1
so that the max(y)
is as big as possible and the probe doesn’t overshoot the target area when falling.
I got this idea after drawing the example with initial velocity of 6,9
:
.....................#.........
.....................#.........
...............................
.....................#.........
...............................
...............................
.....................#.........
...............................
...............................
...............................
....................##.........
...............................
...............................
...............................
...............................
..................#..#.........
...............................
...............................
...............................
...............................
...............................
...............#.....#.........
...............................
...............................
...............................
...............................
...............................
...............................
...........#.........#.........
...............................
...............................
...............................
...............................
...............................
...............................
...............................
......#..............#.........
...............................
...............................
...............................
...............................
...............................
...............................
...............................
...............................
S....................#.........
...............................
...............................
...............................
...............................
....................TTTTTTTTTTT
....................TTTTTTTTTTT
....................TTTTTTTTTTT
....................TTTTTTTTTTT
....................TTTTTTTTTTT
....................T#TTTTTTTTT
Yes, your formula for y
works for part 1 with my input. My input is:
target area: x=185..221, y=-122..-74
and the best initial velocity is {19, 121}
.
Here’s my solution.
I’m not sure if this is the best approach, but using streams to determine the trajectory turned out pretty nice imho.
Runs in 2.5s for both parts on my machine.
Part 1 can be solved with a simple approach.
target_y_range = -85..-56
max_vy = -1 - target_y_range.first
div(max_vy * (max_vy + 1), 2)
My full solution for day 17.
I did the same thing for part 1
def solve_part1([_x1, _x2, y1, _y2]), do: div(y1 * (y1 + 1), 2)
A bit of brute force shooting, the only mathy thing happening is that the max height is calculated from the initial vertical velocity. For shits & giggles I also made a version that shoots every projectile on its own thread. I was shocked to find that was not even faster!
Right, so I somehow absolutely did not want to brute force, so instead I implemented a thing where
{x, min_steps, stays_in_target_area?, max_steps}
{y, min_steps, max_steps}
)y < 0
(and all the positive ones are can be calculated from these)and then for part one sort the ys, and get the first one for which we can find an x with corresponding steps
now for part two I ended up doing two approaches (which at least on this input data end up being equivalent performance wise)
%{nr_of_steps => %{ x: [list, of, x, velocities, in, this, amount, of, steps], y: [list, of, y, velocities, ...] }, ...}
, and then do a Cartesian product of all the xes and ysAnyhow, here’s the code for the curious: aoc/day-17.ex at 3bf7bf357a7431f427c0a0647dc163aeba73fc38 · ramuuns/aoc · GitHub
My approach is kinda brute force but it still runs in under 1 second on my laptop. The way I wrote part 1 I had all the target hits already, so part two was just swapping a count in for where I was getting the max.
Random question - Is there a cleaner/better way to do a ternary for assignment than this?
highest_peak = if y > highest_peak, do: y, else: highest_peak
Coming from a JavaScript/TypeScript background I’m used to doing something like:
highestPeak = y > highestPeak ? y : highestPeak
I’m just wondering if there is a terse syntax like this I can use in Elixir.
y > highestPeak && y || highestPeak
Thank you! I knew there had to be a way.
def part_2 do
target = parse_input()
vels =
for x <- 0..target.x_range.last,
y <- target.y_range.first..-target.y_range.first do
{x, y}
end
Enum.count(vels, &valid?(&1, target))
end
Runs in 52ms. Full solution here
Definitely feels like I’m missing something, but brute force worked well enough on my input: