Advent of Code 2022 Say 24 - Discussions

This topic is about Day 24 of the Advent of Code 2022 .

Link to our leaderboard:

https://adventofcode.com/2022/leaderboard/private/view/370884

The entry code is:
370884-a6a71927

We are at 196 right now and 200 is the cap, in case the leaderboard fills up and you are unable to join, please join the following:

https://adventofcode.com/2022/leaderboard/private/view/257223

And the code for this leaderboard is: 257223-1bcda624

Penultimate Puzzle is upon us folks! Good luck!!

2 Likes

There are probably some better ways of solving this, but I just used same search approach from day 12, slightly modified:

main(File) ->
    {ok, RawData} = file:read_file(File),
    Data = [ [ X || X <- binary_to_list(Line) ]
        || Line <- binary:split(RawData, <<"\n">>, [global, trim]) ],
    Map = load(Data),
    io:format("part 1: ~p~n", [solve1(Map)]),
    io:format("part 2: ~p~n", [solve2(Map)]).

load(Data) ->
    maps:from_list([ {{X, Y}, case N of $. -> [];
                                        _  -> [N]
                              end}
                      || {Y, Line} <- lists:enumerate(Data),
                         {X, N}    <- lists:enumerate(Line),
                         N =/= $# ]).

solve1(Map) ->
    Start = [{0, {2, 1}}],
    End   = {MaxX, MaxY} = lists:max(maps:keys(Map)),
    {Best, _} = search(Start, End, {MaxX, MaxY - 1}, #{0 => Map}),
    Best.

solve2(Map) ->
    Start    = {2, 1},
    End      = {MaxX, MaxY} = lists:max(maps:keys(Map)),
    MaxCoord = {MaxX, MaxY - 1},
    {Best1, Map1} = search([{0,     Start}], End,   MaxCoord, #{0     => Map}),
    {Best2, Map2} = search([{Best1, End}],   Start, MaxCoord, #{Best1 => Map1}),
    {Best3, _}    = search([{Best2, Start}], End,   MaxCoord, #{Best2 => Map2}),
    Best3.

simulate(Map, Maxs) ->
    maps:fold(fun (K, V, Acc) -> fold_blizzard(K, V, Maxs, Acc) end, #{}, Map).

fold_blizzard(_, [],   {_,    _   }, Acc) -> Acc;
fold_blizzard(C, Dirs, {MaxX, MaxY}, Acc) ->
    lists:foldl(fun (D, Acc0) -> do_move_blizzard(D, C, {MaxX, MaxY}, Acc0) end, Acc, Dirs).

do_move_blizzard(Dir, {X, Y}, {MaxX, MaxY}, Map) ->
    NewC = case Dir of
               $> when X < MaxX -> {X + 1, Y};
               $>               -> {2,     Y};
               $< when X > 2    -> {X - 1, Y};
               $<               -> {MaxX,  Y};
               $v when Y < MaxY -> {X, Y + 1};
               $v               -> {X, 2    };
               $^ when Y > 2    -> {X, Y - 1};
               $^               -> {X, MaxY }
           end,
    maps:update_with(NewC, fun(V) -> [Dir|V] end, [Dir], Map).

search(Start, End, MaxCoord, Maps) ->
    search(Start, End, MaxCoord, #{}, inf, Maps).

search([], _, _, _Seen, Best, Maps) ->
    {Best, maps:get(Best, Maps)};
search([{Len, End}|Rest], End, MaxCoord, Seen, Best, Maps) when Len < Best ->
    search(Rest, End, MaxCoord, Seen, Len, Maps);
search([{Len, Coord}|Rest], End, MaxCoord, Seen, Best, Maps) ->
    case Len >= Best of
        true  -> search(Rest, End, MaxCoord, Seen, Best, Maps);
        false ->
            NewSeen  = Seen#{{Len, Coord} => ok},
            NewMaps  = case maps:is_key(Len + 1, Maps) of
                           false -> Maps#{Len + 1 => simulate(maps:get(Len, Maps), MaxCoord)};
                           true  -> Maps
                       end,
            ToFollow = lists:sort([ {Len + 1, C} || C <- adjacent_coords(Coord, MaxCoord, End),
                                                    not maps:is_key({Len + 1, C}, Seen),
                                                    not maps:is_key(C, maps:get(Len + 1, NewMaps)) ]),
            search(ordsets:union(ToFollow, Rest), End, MaxCoord, NewSeen, Best, NewMaps)
    end.

adjacent_coords({X, Y}, _, {EndX, EndY}) when X =:= EndX, Y =:= EndY - 1;
                                              X =:= EndX, Y =:= EndY + 1 ->
    [{X, EndY}];
adjacent_coords({X, Y}, {MaxX, MaxY}, _) ->
    MaybeWait = case {X, Y} of
                    {2, 1}                     -> [{X, Y}];
                    {X, Y} when Y =:= MaxY + 1 -> [{X, Y}];
                    _                          -> []
                end,
    [ {A, B} || {A, B} <- [{X + 1, Y},
                           {X,     Y + 1},
                           {X - 1, Y},
                           {X,     Y - 1},
                           {X,     Y}],
                A =< MaxX, B =< MaxY,
                A >= 2,    B >= 2 ] ++ MaybeWait.
2 Likes