1
0
Fork 0
advent-of-code/2017/day23/day23.erl

106 lines
4.6 KiB
Erlang

-module(day23).
-export([start/0]).
value_or_register(X, Registers)
when X >= <<"a">>, X =< <<"z">> -> maps:get(X, Registers, 0);
value_or_register(X, _Registers)
-> { NewValue, _ } = string:to_integer(X),
NewValue.
format_input(Input)
-> lists:map(fun(X) -> [A|Args] = re:split(X, " "), { A, Args } end, re:split(Input, "\n")).
assemble(Input)
-> Instructions = format_input(Input),
assemble(Instructions, length(Instructions), 1, 0, maps:new()).
debug_assemble(Input)
-> Instructions = format_input(Input),
assemble(Instructions, length(Instructions), 1, 0, maps:put(<<"a">>, 1, maps:new())).
assemble(_Instructions, MaxInstructions, Ip, LastFrequency, Registers)
when Ip < 1; Ip > MaxInstructions -> { LastFrequency, Registers };
assemble(Instructions, MaxInstructions, Ip, LastFrequency, Registers)
-> { Op, Args } = lists:nth(Ip, Instructions),
%io:fwrite("ip ~p op ~p args ~p~n~p~n", [Ip, Op, Args, Registers]),
case Op of
<<"add">> ->
[Src,Dest|_] = Args,
ExistingValue = maps:get(Src, Registers, 0),
NewValue = value_or_register(Dest, Registers),
assemble(Instructions, MaxInstructions, Ip + 1, LastFrequency, maps:put(Src, ExistingValue + NewValue, Registers));
<<"sub">> ->
[Src,Dest|_] = Args,
ExistingValue = maps:get(Src, Registers, 0),
NewValue = value_or_register(Dest, Registers),
assemble(Instructions, MaxInstructions, Ip + 1, LastFrequency, maps:put(Src, ExistingValue - NewValue, Registers));
<<"jnz">> ->
[Src,Dest|_] = Args,
SrcValue = value_or_register(Src, Registers),
NewValue = value_or_register(Dest, Registers),
if SrcValue /= 0 -> assemble(Instructions, MaxInstructions, Ip + NewValue, LastFrequency, Registers);
true -> assemble(Instructions, MaxInstructions, Ip + 1, LastFrequency, Registers)
end;
<<"jgz">> ->
[Src,Dest|_] = Args,
SrcValue = value_or_register(Src, Registers),
NewValue = value_or_register(Dest, Registers),
if SrcValue > 0 -> assemble(Instructions, MaxInstructions, Ip + NewValue, LastFrequency, Registers);
true -> assemble(Instructions, MaxInstructions, Ip + 1, LastFrequency, Registers)
end;
<<"mod">> ->
[Src,Dest|_] = Args,
ExistingValue = maps:get(Src, Registers, 0),
NewValue = value_or_register(Dest, Registers),
assemble(Instructions, MaxInstructions, Ip + 1, LastFrequency, maps:put(Src, ExistingValue rem NewValue, Registers));
<<"mul">> ->
[Src,Dest|_] = Args,
ExistingValue = maps:get(Src, Registers, 0),
NewValue = value_or_register(Dest, Registers),
Registers2 = maps:put("mul_count", maps:get("mul_count", Registers, 0) + 1, Registers),
assemble(Instructions, MaxInstructions, Ip + 1, LastFrequency, maps:put(Src, ExistingValue * NewValue, Registers2));
<<"rcv">> ->
[Dest|_] = Args,
NewValue = value_or_register(Dest, Registers),
if NewValue /= 0 -> LastFrequency;
true -> assemble(Instructions, MaxInstructions, Ip + 1, LastFrequency, Registers)
end;
<<"set">> ->
[Src,Dest|_] = Args,
NewValue = value_or_register(Dest, Registers),
assemble(Instructions, MaxInstructions, Ip + 1, LastFrequency, maps:put(Src, NewValue, Registers));
<<"snd">> ->
[Dest|_] = Args,
NewValue = value_or_register(Dest, Registers),
assemble(Instructions, MaxInstructions, Ip + 1, NewValue, Registers);
<<>> ->
io:fwrite("invalid instruction: ~p~n", [{ Op, Args }]),
assemble(Instructions, MaxInstructions, Ip + 1, LastFrequency, Registers)
end.
is_prime(Check)
-> is_prime(Check, 2, math:sqrt(Check)).
is_prime(Check, Min, _Max)
when Check rem Min == 0 -> false;
is_prime(Check, Min, Max)
when Min > Max -> Check /= 1;
is_prime(Check, Min, Max)
-> is_prime(Check, Min + 1, Max).
get_num_nonprimes(Start, End)
-> get_num_nonprimes(Start, End, 1, is_prime(Start)).
get_num_nonprimes(Start, End, Count, _IsPrime)
when Start == End -> Count;
get_num_nonprimes(Start, End, Count, IsPrime)
when IsPrime -> NewStart = Start + 17,
get_num_nonprimes(NewStart, End, Count, is_prime(NewStart));
get_num_nonprimes(Start, End, Count, IsPrime)
when not IsPrime -> NewStart = Start + 17,
get_num_nonprimes(NewStart, End, Count + 1, is_prime(NewStart)).
start()
-> { ok, File } = file:read_file("problem"),
io:fwrite("~p~n", [ assemble(File) ]),
%io:fwrite("~p~n", [ debug_assemble(File) ]).
io:fwrite("~p~n", [ get_num_nonprimes(109900, 126900) ]).