This topic is about Day 17 of the Advent of Code 2021.
We have a private leaderboard (shared with users of the elixir forum):
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 the elixir forum):
https://adventofcode.com/2021/leaderboard/private/view/370884
The entry code is:
370884-a6a71927
I thought I needed some fancy maths to do this. Turns out I did not
Same, initially I solved it with brute force with some arbitrary bound on dy
, like 1000, and it was still fast enough to iterate through all initial {dx,dy}
combinations in a second or so. Later I tried to optimise it and be smart, but only figured out limit on dy
is abs(min_y)
from the input, that only works for max_y
< start_y
so :
main(File) ->
{ok, RawData} = file:read_file(File),
{match, RawTarget} = re:run(RawData, <<"([-\\d]+)">>, [{capture, all_but_first, list}, global]),
Target = list_to_tuple([ list_to_integer(X) || [X] <- RawTarget ]),
io:format("part 1: ~p~n", [solve1(Target)]),
io:format("part 2: ~p~n", [solve2(Target)]).
solve1(Target) ->
lists:max(heights(Target)).
solve2(Target) ->
length(heights(Target)).
heights({_MinX, MaxX, MinY, _MaxY} = Target) ->
[ H || X <- lists:seq(1, MaxX),
Y <- lists:seq(MinY, abs(MinY)),
(H = iter_steps({X, Y}, Target)) =/= false ].
iter_steps(V, Target) ->
iter_steps(V, Target, {0, 0}, 0).
iter_steps(V, Target, {_, Y} = C, H) ->
case position(C, Target) of
hit ->
H;
continue ->
{NewV, NewC} = step(V, C),
iter_steps(NewV, Target, NewC, max(Y, H));
_ ->
false
end.
step({Dx, Dy}, {X, Y}) ->
{{max(0, Dx - 1), Dy - 1}, {X + Dx, Y + Dy}}.
position({X, Y}, { MinX, MaxX, MinY, MaxY}) when X >= MinX, X =< MaxX, Y >= MinY, Y =< MaxY -> hit;
position({X, _Y}, {_MinX, MaxX, _MinY, _MaxY}) when X > MaxX -> over;
position({_, Y}, {_MinX, _MaxX, MinY, _MaxY}) when Y < MinY -> under;
position(_XY, _Target) -> continue.
Much more fun with fancy math though. It’s possible to generate initial x and y velocity backward from a target coordinate using arithmetic progression.
However, I needed to apply a brute force version eventually to the second part to compare results and find missing pairs caused by a small bug in the fancy math