You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

52 lines
1.5 KiB

-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(<<Digit, Rest/binary>>, Acc) when Digit >= $0 andalso Digit =< $9 ->
parse_int0(Rest, Acc*10 + Digit - $0);
parse_int0(Binary, Acc) when is_binary(Binary) -> {Acc, Binary}.