Advent of Code 2022 Day 21 - Discussions

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

Smells like reactive programming to me!

2 Likes

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 ->
            null;
        Integer when is_integer(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}
            end
    end.

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)
    end;
inverse(V, null) ->
    V.
2 Likes

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!

3 Likes

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!

2 Likes

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.

4 Likes