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
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}.
|