Advent of Code 2022 Day 21 - Discussions

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

Link to our leaderboard:

The entry code is:

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:

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

Good luck!


Smells like reactive programming to me!


Fun equation solving today :slight_smile:

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

parse_monkey(<<Name:4/binary, ": ", Rest/binary>>) ->
    {Name, parse_monkey_value(Rest)}.

parse_monkey_value(<<N1:4/binary, " ", Op:1/binary, " ", N2:4/binary>>) -> {N1, Op, N2};
parse_monkey_value(V) -> binary_to_integer(V).

solve1(Data) ->
    stack(<<"root">>, Data).

solve2(Data0) ->
    Data = maps:remove(<<"humn">>, Data0),
    {R1, _, R2} = maps:get(<<"root">>, Data),
    S1 = stack(R1, Data),
    S2 = stack(R2, Data),
    inverse(S1, S2).

stack(M, Data) ->
    case maps:get(M, Data, null) of
        null ->
        Integer when is_integer(Integer) ->
        {M1, Op, M2} ->
            S1 = stack(M1, Data),
            S2 = stack(M2, Data),
            case is_integer(S1) andalso is_integer(S2) of
                true  -> op(Op, S1, S2);
                false -> {Op, S1, S2}

op(<<"+">>, X, Y) -> X + Y;
op(<<"-">>, X, Y) -> X - Y;
op(<<"*">>, X, Y) -> X * Y;
op(<<"/">>, X, Y) -> X div Y.

inverse(S1, V) when is_integer(V) ->
    inverse(V, S1);
inverse(V, {Op, V1, V2}) ->
    case Op of
        <<"+">> when is_integer(V1) -> inverse(V - V1, V2);
        <<"+">>                     -> inverse(V - V2, V1);
        <<"*">> when is_integer(V1) -> inverse(V div V1, V2);
        <<"*">>                     -> inverse(V div V2, V1);
        <<"-">> when is_integer(V1) -> inverse(V1 - V, V2);
        <<"-">>                     -> inverse(V + V2, V1);
        <<"/">> when is_integer(V1) -> inverse(V1 div V, V2);
        <<"/">>                     -> inverse(V * V2, V1)
inverse(V, null) ->

So I used a GenServer based one at first, only to realize part 2 will require me to do lots of ups and downs, so I went for the recursion path. Also, my inversion function was a lot messier with usage of apply so I stole your inverse :stuck_out_tongue:

It was Elixir again for me!


I also went for an asynchronous, process-based approach for part 1, because I had been really hoping to solve at least one puzzle this way. Too bad AoC is designed primarily for languages with inferior concurrency models!


Advent of Code 2019 had several puzzles that involved concurrency, for example Day 23 where one had to simulate 50 computers in a network.

It is a good year of Advent of Code to do for anyone who like crafting interpreters. Already in Day 2 a virtual machine called Intcode is introduced, and it is then used in many of the puzzles that follow.