Advent of Code 2022 Day 10 - Discussions

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

Link to our leaderboard:

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

The entry code is:
370884-a6a71927

Good luck!

2 Likes

Today was fun, but I had to re-read Part 2 five times to understand what was happening (maybe because it’s 5AM here, idk):

main(File) ->
    {ok, RawData} = file:read_file(File),
    Data = [ case Line of
                 <<"noop">> -> noop;
                 <<"addx ", V/binary>> -> {addx, binary_to_integer(V)}
             end || Line <- binary:split(RawData, <<"\n">>, [global, trim]) ],
    io:format("part 1: ~p~n", [solve1(Data)]),
    io:format("part 2: ~p~n", [solve2(Data)]).

solve1(Data) ->
    Values = simulate(Data, 1, 1),
    lists:sum([ K * element(2, lists:keyfind(K, 1, Values)) || K <- lists:seq(20, 220, 40) ]).

solve2(Data) ->
    lists:foreach(fun draw/1, simulate(Data, 1, 1)).

simulate([], _, _)            -> [];
simulate([Op|Rest], C, Value) ->
    case Op of
        noop          -> [{C, Value}                |simulate(Rest, C + 1, Value)];
        {addx, ToAdd} -> [{C, Value}, {C + 1, Value}|simulate(Rest, C + 2, Value + ToAdd)]
    end.

draw({Cycle, X}) ->
    Shifted = Cycle - 40 * (Cycle div 40) - 1,
    case Shifted >= (X - 1) andalso Shifted =< (X + 1) of
        true  -> io:format("#");
        false -> io:format(".")
    end,
    case Cycle rem 40 of
        0 -> io:format("\n");
        _ -> ok
    end.
2 Likes
-module(day_10).

-export([solve/0]).

-define(print, "█").
-define(blank, "▒").

input() ->
  element(2, file:read_file("data/10.txt")).

solve() ->
  {Cycles, _, _} = run(parse(input())),
  Nths = [20, 60, 100, 140, 180, 220],
  Solve1 = lists:sum([X * element(2, lists:keyfind(X, 1, Cycles)) || X <- Nths]),
  Solve2 =
    lists:foreach(fun render/1, lists:sort(fun({X, _}, {Y, _}) -> X < Y end, Cycles)),
  {Solve1, Solve2}.

parse(RawInstructions) ->
  [parse_instruction(RawInstruction)
   || RawInstruction <- binary:split(RawInstructions, <<"\n">>, [global, trim])].

parse_instruction(<<"noop">>) ->
  noop;
parse_instruction(<<"addx ", Val/binary>>) ->
  binary_to_integer(Val).

run(Instructions) ->
  lists:foldl(fun (noop, {Xs, Cycle, Value}) ->
                    {[{Cycle, Value} | Xs], Cycle + 1, Value};
                  (AddValue, {Xs, Cycle, Value}) when is_integer(AddValue) ->
                    {[{Cycle, Value}, {Cycle + 1, Value} | Xs], Cycle + 2, Value + AddValue}
              end,
              {[], 1, 1},
              Instructions).

render({Cycle, X}) ->
  Shift = Cycle - 40 * (Cycle div 40) - 1,
  if Shift >= X - 1 andalso Shift =< X + 1 ->
       io:format(?print);
     true ->
       io:format(?blank)
  end,
  if Cycle rem 40 == 0 ->
       io:format("\n");
     true ->
       ok
  end.
2 Likes

Messy solution but works; and borrowed the render from @mafinar as I didn’t understand the how they wanted it rendered.



-module(day10).

-compile([export_all]).
%% ====================================================================
%% API functions
%% ====================================================================
-export([p1/0,
		 p2/0]).

-define(print, "█").
-define(blank, "▒").
s() ->
	?MODULE ! stop.

p1() ->
	proc_lib:spawn_link(?MODULE, init, [self(), #{}]),
	receive after 500 -> void end, 
	loop_r(0).

p2() ->
	proc_lib:spawn_link(?MODULE, init2, [self(), #{}]),
		receive after 500 -> void end, 
	[catch render(I) || I <- lists:keysort(1, loop_2([]))].
	
loop_2(Mem) ->
	receive 
		{ack,_,_} ->
			loop_2(Mem);
		I -> 
			loop_2([I|Mem])

	after 0 -> 
		Mem
	end.


loop_r(Cnt) ->
	receive 
		Int when is_integer(Int) ->
			loop_r(Cnt+Int);
		_ ->
			%% ignore
			loop_r(Cnt)
	after 0 -> 
		Cnt
	end.

init2(PPid, Map) ->
	proc_lib:init_ack(PPid, {ok, self()}),
	register(?MODULE,self()),
	Input = input(),
	loop2(Map#{ppid => PPid,
		 inst => Input,
		 cur_inst => noop,
		 x => 1,
		 cycle => 1
		}).


loop2({stop, State}) ->
	exit(normal);
loop2(State) ->
	NS = case maps:get(cycle, State) of
			 240 ->
				 {stop, State};
		 _ ->
			step2(State)
	end,
	loop2(NS).

init(PPid, Map) ->
	proc_lib:init_ack(PPid, {ok, self()}),
	register(?MODULE,self()),
	Input = input(),
	loop(Map#{ppid => PPid,
		 inst => Input,
		 cur_inst => noop,
		 x => 1,
		 cycle => 1
		}).


loop({stop, State}) ->
	exit(normal);
loop(State) ->
	NS = receive
		stop -> {stop, State}
	after 0->
		step(State)
	end,
	loop(NS).

step(Map) ->
	Cycle = maps:get(cycle, Map),
	LastInst = maps:get(cur_inst, Map),
	Instructions = maps:get(inst, Map),
	RunInst = hd(Instructions), 
	RestInst = tl(Instructions),
	NM = run( RunInst,Cycle, Map#{inst => RestInst}), 
	notifiable(Cycle+1, NM).

step2(Map) ->
	Cycle = maps:get(cycle, Map),
	LastInst = maps:get(cur_inst, Map),
	Instructions = maps:get(inst, Map),
	RunInst = hd(Instructions), 
	PPid = maps:get(ppid, Map), 
	RestInst = tl(Instructions),
	X = maps:get(x, Map), 
	PPid ! {Cycle, X},
	 run( RunInst,Cycle, Map#{inst => RestInst}).

run(noop,Cycle,Map) ->
	Map#{cycle => Cycle+1, cur_inst => noop};
run(addx, Cycle, Map) ->
	Map#{cycle => Cycle+1, cur_inst => addx};
run(Num, Cycle, Map) ->
	X = maps:get(x, Map),
	Map#{cycle => Cycle+1, x => X+Num}.

notifiable(NM, Map) when NM == 20;
			 NM == 60;
			 NM == 100;
			 NM == 140;
			 NM == 180;
						 NM == 220->

		Val = maps:get(x, Map),
		PPid = maps:get(ppid, Map),
		
		catch PPid ! NM * Val,
	if (NM == 220 ) ->{stop, Map};
 true -> Map
end;
		
notifiable(NM, Map) ->
	Map.

render({Cycle, X}) ->
  Shift = Cycle - 40 * (Cycle div 40) - 1,
  if Shift >= X - 1 andalso Shift =< X + 1 ->
       io:format(?print);
     true ->
       io:format(?blank)
  end,
  if Cycle rem 40 == 0 ->
       io:format("\n");
     true ->
       ok
  end.


%% ====================================================================
%% Internal functions
%% ====================================================================

input() ->
	{ok, B} = file:read_file("priv/input.txt"),
	parse_to_wanted(binary:split(B, [<<10>>, <<" ">>], [global, trim])).

parse_to_wanted([]) ->
	[];
parse_to_wanted([<<"addx">>|Rest]) ->
	[addx|parse_to_wanted(Rest)];
parse_to_wanted([<<"noop">>|Rest]) ->
	[noop|parse_to_wanted(Rest)];
parse_to_wanted([E|Rest]) ->
	[binary_to_integer(E)|parse_to_wanted(Rest)].
3 Likes