-module(day10). -export([solve/1]). solve(Input) -> {part1(Input), io:format("~s~n", [part2(Input)])}. part1(Input) -> History = run(Input, [{1, 1}]), Interesting = [20, 60, 100, 140, 180, 220], Score = fun(Key) -> Key * element(2, lists:keyfind(Key, 1, History)) end, lists:sum(lists:map(Score, Interesting)). part2(Input) -> History = run(Input, [{1, 1}]), render(History, []). render([{Cycle, X}|Rest], Acc) -> Prefix = case Cycle rem 40 == 0 of true -> "\n"; false -> [] end, Symbol = if X + 2 < Cycle rem 40 -> $.; X > Cycle rem 40 -> $.; true -> $# end, render(Rest, [Symbol|Prefix] ++ Acc); render([], Acc) -> Acc. run(<<"\n", Rest/binary>>, StateIn) -> run(Rest, StateIn); run(<<"noop", Rest/binary>>, [{Cycle, X}|_]=History) -> run(Rest, [{Cycle+1, X} | History]); run(<<"addx ", RestIn/binary>>, [{Cycle, X}|_]=History) -> {Value, RestOut} = parse_int(RestIn), run(RestOut, [{Cycle+2, X+Value}, {Cycle+1, X} | History]); run(<<>>, State) -> State. parse_int(<<$-, Rest/binary>>) -> {AbsoluteValue, Binary} = parse_int0(Rest, 0), {-1 * AbsoluteValue, Binary}; parse_int(Binary) -> parse_int0(Binary, 0). parse_int0(<>, Acc) when Digit >= $0 andalso Digit =< $9 -> parse_int0(Rest, Acc*10 + Digit - $0); parse_int0(Binary, Acc) when is_binary(Binary) -> {Acc, Binary}.