day23 solution, helped by reddit
parent
0c219c6f2f
commit
a31b1a4142
|
@ -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
|
|
@ -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) ]).
|
|
@ -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
|
Loading…
Reference in New Issue