Advent of Code 2022 Day 23 - Discussion

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

Good luck!

2 Likes

Took absolutely forever to debug because I forgot about the “Elf doesn’t move if no Elves around” rule :-/
Anyway here is ugly code :slight_smile:

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

load(Data) ->
    maps:from_list([ {{X, Y}, N} || {Y, Line} <- lists:enumerate(Data),
                                    {X, N}    <- lists:enumerate(Line),
                                    N ]).

solve1(Map) ->
    NewMap = simulate(Map, 10),
    {Xs, Ys} = lists:unzip(maps:keys(NewMap)),
    (lists:max(Xs) - lists:min(Xs) + 1)
  * (lists:max(Ys) - lists:min(Ys) + 1)
  - maps:size(NewMap).

solve2(Map) ->
    simulate(Map, -1).

simulate(Map, N) ->
    Order = [
        [ {X, -1} || X <- [-1, 0, 1] ],
        [ {X,  1} || X <- [-1, 0, 1] ],
        [ {-1, Y} || Y <- [-1, 0, 1] ],
        [ { 1, Y} || Y <- [-1, 0, 1] ]
    ],
    iteration({Map, Order}, N).

iteration({Map, _},     0) -> Map;
iteration({Map, Order}, N) ->
    Elves     = maps:keys(Map),
    Proposals = [ propose(E, Order, Map) || E <- Elves ],
    Moves     = maps:groups_from_list(fun ({To, _From}) -> To end, Proposals),
    NewMap    = new_map(Moves),
    case N < 0 andalso NewMap =:= Map of
        true  -> -N;
        false -> iteration({NewMap, tl(Order) ++ [hd(Order)]}, N - 1)
    end.

new_map(List) ->
    lists:foldl(fun new_map/2, #{}, maps:to_list(List)).

new_map({C, [_]},             Map) -> Map#{C => true};
new_map({_, [_, _|_] = List}, Map) ->
    lists:foldl(fun ({_, From}, Acc) -> Acc#{From => true} end, Map, List).

propose(C, Order, Map) ->
    S      = lists:seq(-1, 1),
    Around = [ {X, Y} || X <- S, Y <- S, {X, Y} =/= {0, 0} ],
    case have_elves(C, Around, Map) of
        false -> {C, C};
        true  -> do_propose(C, Order, Map)
    end.

do_propose(C, [],       _Map) -> {C, C};
do_propose(C, [O|Order], Map) ->
    case have_elves(C, O, Map) of
        false -> {plus(C, lists:nth(2, O)), C};
        true  -> do_propose(C, Order, Map)
    end.

have_elves(C, List, Map) when is_list(List) ->
    lists:any(fun (D) -> maps:is_key(plus(C, D), Map) end, List).

plus({X, Y}, {A, B}) ->
    {X + A, Y + B}.

print(Map0) ->
    Map = [ K || {K, _} <- maps:to_list(Map0) ],
    MinX = lists:min([ X || {X, _} <- Map ]),
    MaxX = lists:max([ X || {X, _} <- Map ]),
    MinY = lists:min([ Y || {_, Y} <- Map ]),
    MaxY = lists:max([ Y || {_, Y} <- Map ]),
    [ print(Map, MinX, MaxX, Y) || Y <- lists:seq(MinY - 1, MaxY + 1) ],
    io:format("~n").

print(Map, MinX, MaxX, Y) ->
    Dots = [ X || {X, Y0} <- Map, Y0 =:= Y ],
    [ case lists:member(X, Dots) of
          true  -> io:format("#");
          false -> io:format(".")
      end || X <- lists:seq(MinX, MaxX) ],
    io:format("~n").
1 Like