Advent of Code 2022 Day 14 - Discussions

This topic is about Day 14 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!

2 Likes

After polishing the code I ended up with something like that :slight_smile:

main(File) ->
    {ok, RawData} = file:read_file(File),
    Data0 = [ [ begin
                   [A, B] = binary:split(T, <<",">>),
                   {binary_to_integer(A), binary_to_integer(B)}
                end
                || T <- binary:split(X, <<" -> ">>, [global, trim]) ]
              || X <- binary:split(RawData, <<"\n">>, [global, trim]) ],
    Data = sets:from_list(lists:append(lists:map(fun to_dots/1, Data0)), [{version, 2}]),
    io:format("part 1: ~p~n", [solve1(Data)]),
    io:format("part 2: ~p~n", [solve2(Data)]).

solve1(Map) ->
    sets:size(simulate(false, Map)) - sets:size(Map).

solve2(Map) ->
    sets:size(simulate(true, Map)) - sets:size(Map).

simulate(HaveFloor, Map) ->
    Start = {500, 0},
    End   = lists:max([ Y || {_, Y} <- maps:keys(Map) ]) + 2,
    drop_sand(Start, Start, End, HaveFloor, Map).

drop_sand({_, End},   _Start, End, false,            Map) -> Map;
drop_sand({_, Y} = C,  Start, End, HaveFloor = true, Map)
  when (Y + 1) =:= End ->
    drop_sand(Start, Start, End, HaveFloor, sets:add_element(C, Map));
drop_sand({X, Y} = C, Start, End, HaveFloor, Map) ->
    Options = [{X, Y + 1}, {X - 1, Y + 1}, {X + 1, Y + 1}],
    case lists:search(fun (N) -> not sets:is_element(N, Map) end, Options) of
        {value, NextCoord} ->
            drop_sand(NextCoord, Start, End, HaveFloor, Map);
        false ->
            NewMap = sets:add_element(C, Map),
            case C of
                Start -> NewMap;
                _     -> drop_sand(Start, Start, End, HaveFloor, NewMap)
            end
    end.

to_dots([_]) -> [];
to_dots([{X1, Y1}, {X2, Y2} = B|Rest]) ->
    [ {X, Y} || X <- from_to(X1, X2),
                Y <- from_to(Y1, Y2) ]
 ++ to_dots([B|Rest]).

from_to(A, B) ->
    case B > A of
        true  -> lists:seq(A, B);
        false -> lists:seq(A, B, -1)
    end.
2 Likes