This topic is about Day 15 of the Advent of Code 2022 .
Link to our leaderboard:
https://adventofcode.com/2022/leaderboard/private/view/370884
The entry code is:
370884-a6a71927
Good luck!
This topic is about Day 15 of the Advent of Code 2022 .
Link to our leaderboard:
https://adventofcode.com/2022/leaderboard/private/view/370884
The entry code is:
370884-a6a71927
Good luck!
Not the most optimal solution, takes about 3.5s on my machine to compute, but does the job anyway :
main(File) ->
{ok, RawData} = file:read_file(File),
Data = [ begin
[Xs, Ys, Xb, Yb] = get_integers(X),
Sensor = {Xs, Ys},
Beacon = {Xb, Yb},
{Sensor, Beacon, distance(Sensor, Beacon)}
end || X <- binary:split(RawData, <<"\n">>, [global, trim]) ],
io:format("part 1: ~p~n", [solve1(Data)]),
io:format("part 2: ~p~n", [solve2(Data)]).
get_integers(Bin) ->
{match, Match} = re:run(Bin, <<"([-\\d]+)">>, [{capture, all_but_first, binary}, global]),
[ binary_to_integer(X) || [X] <- Match ].
solve1(Data) ->
ordsets:size(ordsets:union([ empty_positions(X, 2000000) || X <- Data ])).
solve2(Data) ->
{X, Y} = find_empty_coordinate(0, 0, Data, 4000000),
X * 4000000 + Y.
find_empty_coordinate(X, Y, Map, Limit) when X =< Limit, Y =< Limit ->
case first_edge(X, Y, Map) of
{ok, NewX} when NewX >= Limit -> find_empty_coordinate(0, Y + 1, Map, Limit);
{ok, NewX} -> find_empty_coordinate(NewX + 1, Y, Map, Limit);
false -> {X, Y}
end.
first_edge(_, _, []) -> false;
first_edge(X, Y, [{{Xs, Ys}, _, Distance}|Rest]) ->
DotDistance = abs(Xs - X) + abs(Ys - Y),
case DotDistance > Distance of
true -> first_edge(X, Y, Rest);
false -> {ok, Xs + (Distance - abs(Ys - Y))}
end.
empty_positions({{Xs, Ys}, {Xb, Yb}, Distance}, Y) ->
YDistance = abs(Ys - Y),
case YDistance > Distance of
true -> [];
false ->
S0 = lists:seq(Xs - (Distance - YDistance), Xs + (Distance - YDistance)),
case Yb of
Y -> S0 -- [Xb];
_ -> S0
end
end.
distance({X1, Y1}, {X2, Y2}) ->
abs(X1 - X2) + abs(Y1 - Y2).