Advent of Code 2021 - Day 24

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

We have a private leaderboard (shared with users of the elixir forum):

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

The entry code is:
370884-a6a71927

3 Likes

Oof, took too long to realize that x and y don’t carry between inputs and then figure out that formula for each input set is the same with only 3 parameters in it. After that it’s straightforward to see how to limit space of inputs between instruction sets as for each multiply for z - division should happen (because last instruction set can only return 0 if it’s in 0…26 area).

2 Likes

Not sure if that will work on all inputs, but code that works for my is:

main(File) ->
    {ok, RawData} = file:read_file(File),
    Data = parse(RawData),
    io:format("part 1: ~p~n", [solve1(Data)]),
    io:format("part 2: ~p~n", [solve2(Data)]).

parse(Data) ->
    lists:map(fun parse_set/1, binary:split(Data, <<"inp w\n">>, [global, trim_all])).

parse_set(Set) ->
    set_to_params(
        [ begin
              [A, B, C] = binary:split(Line, <<" ">>, [global]),
              {binary_to_atom(A),
               binary_to_atom(B),
               try binary_to_integer(C) catch _:_ -> binary_to_atom(C) end}
          end
          || Line <- binary:split(Set, <<"\n">>, [global, trim]) ]
    ).

solve1(Data) ->
    lists:max(emulate_sets(Data)).

solve2(Data) ->
    lists:min(emulate_sets(Data)).

emulate_sets(Sets) ->
    emulate_sets(Sets, 0, []).

emulate_sets([], 0, InputAcc) ->
    [list_to_integer([ $0 + X || X <- lists:reverse(InputAcc) ])];
emulate_sets([], _State, _InputAcc) ->
    [];
emulate_sets([Set|Sets], State, InputAcc) ->
    [ R || I <- possible_inputs(Set, State),
           R <- emulate_sets(Sets, compute(Set, I, State), [I|InputAcc]) ].

compute({Div, Add1, Add2}, Input, State) ->
    X = case (State rem 26 + Add1) =/= Input of
            true  -> 1;
            false -> 0
        end,
    (State div Div) * (25 * X + 1) + X * (Input + Add2).

set_to_params([{mul,x,0},
               {add,x,z},
               {mod,x,26},
               {'div',z,Div},
               {add,x,Add1},
               {eql,x,w},
               {eql,x,0},
               {mul,y,0},
               {add,y,25},
               {mul,y,x},
               {add,y,1},
               {mul,z,y},
               {mul,y,0},
               {add,y,w},
               {add,y,Add2},
               {mul,y,x},
               {add,z,y}]) ->
    {Div, Add1, Add2}.

possible_inputs({Div, Add1, _Add2}, State) when Div > 1, State rem 26 + Add1 > 9 -> [];
possible_inputs({Div, Add1, _Add2}, State) when Div > 1 ->
    [ I || I <- lists:seq(1, 9), (State rem 26 + Add1) =:= I ];
possible_inputs({Div, _, _}, _State) when Div =:= 1 ->
    lists:seq(1, 9).
4 Likes

I am here because I was just curious if someone was doing this today! I might do it next year. Or not. Merry Xmas!

4 Likes