1
0
Fork 0

day23 solution, helped by reddit

main
Andrew Coleman 2017-12-25 16:18:49 -05:00
parent 0c219c6f2f
commit a31b1a4142
3 changed files with 145 additions and 0 deletions

8
day23/Makefile Normal file
View File

@ -0,0 +1,8 @@
all: day23.beam
erl -noshell -s day23 start -s init stop
day23.beam:
erlc day23.erl
clean:
rm -f day23.beam

105
day23/day23.erl Normal file
View File

@ -0,0 +1,105 @@
-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) ]).

32
day23/problem Normal file
View File

@ -0,0 +1,32 @@
set b 99
set c b
jnz a 2
jnz 1 5
mul b 100
sub b -100000
set c b
sub c -17000
set f 1
set d 2
set e 2
set g d
mul g e
sub g b
jnz g 2
set f 0
sub e -1
set g e
sub g b
jnz g -8
sub d -1
set g d
sub g b
jnz g -13
jnz f 2
sub h -1
set g b
sub g c
jnz g 2
jnz 1 3
sub b -17
jnz 1 -23