day18 solution
parent
fbe2635c5b
commit
162ef6b2f4
|
@ -0,0 +1,8 @@
|
|||
all: day18.beam
|
||||
erl -noshell -s day18 start -s init stop
|
||||
|
||||
day18.beam:
|
||||
erlc day18.erl
|
||||
|
||||
clean:
|
||||
rm -f day18.beam
|
|
@ -0,0 +1,174 @@
|
|||
-module(day18).
|
||||
-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.
|
||||
|
||||
assemble(Input)
|
||||
-> Instructions = lists:map(fun(X) -> [A|Args] = re:split(X, " "), { A, Args } end, re:split(Input, "\n")),
|
||||
assemble(Instructions, length(Instructions), 1, 0, maps:new()).
|
||||
|
||||
assemble(_Instructions, MaxInstructions, Ip, LastFrequency, _Registers)
|
||||
when Ip < 1; Ip > MaxInstructions -> LastFrequency;
|
||||
assemble(Instructions, MaxInstructions, Ip, LastFrequency, Registers)
|
||||
-> { Op, Args } = lists:nth(Ip, Instructions),
|
||||
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));
|
||||
<<"jgz">> ->
|
||||
[Src,Dest|_] = Args,
|
||||
NewValue = value_or_register(Dest, Registers),
|
||||
RegisterValue = maps:get(Src, Registers, 0),
|
||||
if RegisterValue > 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),
|
||||
assemble(Instructions, MaxInstructions, Ip + 1, LastFrequency, maps:put(Src, ExistingValue * NewValue, Registers));
|
||||
<<"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)
|
||||
end.
|
||||
|
||||
assemble2(Input)
|
||||
-> Instructions = lists:map(fun(X) -> [A|Args] = re:split(X, " "), { A, Args } end, re:split(Input, "\n")),
|
||||
assemble2(Instructions, length(Instructions), 1, maps:put(<<"p">>, 0, maps:new()), [], 0, 1, maps:put(<<"p">>, 1, maps:new()), []).
|
||||
|
||||
assemble2(Instructions, MaxInstructions, Ip0, Registers0, Queue0, SndCount, Ip1, Registers1, Queue1)
|
||||
-> { NewIp0, NewRegisters0, NewQueue0, NewQueue1, _ } = assemble3(Instructions, MaxInstructions, Ip0, Registers0, Queue0, Queue1),
|
||||
{ NewIp1, NewRegisters1, AnotherNewQueue1, AnotherNewQueue0, Count } = assemble3(Instructions, MaxInstructions, Ip1, Registers1, NewQueue1, NewQueue0),
|
||||
NewSndCount = SndCount + Count,
|
||||
%io:fwrite("newsndcount ~p~n", [NewSndCount]),
|
||||
%io:fwrite("ip0 ~p ip1 ~p~nq0 ~p~nq1 ~p~n", [NewIp0, NewIp1, AnotherNewQueue0, AnotherNewQueue1]),
|
||||
if Ip0 == NewIp0, Ip1 == NewIp1 -> NewSndCount;
|
||||
true -> assemble2(Instructions, MaxInstructions, NewIp0, NewRegisters0, AnotherNewQueue0, NewSndCount, NewIp1, NewRegisters1, AnotherNewQueue1)
|
||||
end.
|
||||
|
||||
assemble3(_Instructions, MaxInstructions, Ip, Registers, Queue, OtherQueue)
|
||||
when Ip < 1; Ip > MaxInstructions -> { Ip, Registers, Queue, OtherQueue, 0 };
|
||||
assemble3(Instructions, _MaxInstructions, Ip, Registers, Queue, OtherQueue)
|
||||
-> { Op, Args } = lists:nth(Ip, Instructions),
|
||||
case Op of
|
||||
<<"add">> ->
|
||||
[Src,Dest|_] = Args,
|
||||
ExistingValue = maps:get(Src, Registers, 0),
|
||||
NewValue = value_or_register(Dest, Registers),
|
||||
{ Ip + 1, maps:put(Src, ExistingValue + NewValue, Registers), Queue, OtherQueue, 0 };
|
||||
<<"jgz">> ->
|
||||
[Src,Dest|_] = Args,
|
||||
SrcValue = value_or_register(Src, Registers),
|
||||
NewValue = value_or_register(Dest, Registers),
|
||||
if SrcValue > 0 -> { Ip + NewValue, Registers, Queue, OtherQueue, 0 };
|
||||
true -> { Ip + 1, Registers, Queue, OtherQueue, 0 }
|
||||
end;
|
||||
<<"mod">> ->
|
||||
[Src,Dest|_] = Args,
|
||||
ExistingValue = maps:get(Src, Registers, 0),
|
||||
NewValue = value_or_register(Dest, Registers),
|
||||
{ Ip + 1, maps:put(Src, (ExistingValue rem NewValue), Registers), Queue, OtherQueue, 0 };
|
||||
<<"mul">> ->
|
||||
[Src,Dest|_] = Args,
|
||||
ExistingValue = maps:get(Src, Registers, 0),
|
||||
NewValue = value_or_register(Dest, Registers),
|
||||
{ Ip + 1, maps:put(Src, (ExistingValue * NewValue), Registers), Queue, OtherQueue, 0 };
|
||||
<<"rcv">> ->
|
||||
[Dest|_] = Args,
|
||||
QueueLen = length(Queue),
|
||||
if QueueLen == 0 -> { Ip, Registers, Queue, OtherQueue, 0 };
|
||||
true -> [Head|Tail] = Queue, { Ip + 1, maps:put(Dest, Head, Registers), Tail, OtherQueue, 0 }
|
||||
end;
|
||||
<<"set">> ->
|
||||
[Src,Dest|_] = Args,
|
||||
NewValue = value_or_register(Dest, Registers),
|
||||
{ Ip + 1, maps:put(Src, NewValue, Registers), Queue, OtherQueue, 0 };
|
||||
<<"snd">> ->
|
||||
[Dest|_] = Args,
|
||||
NewValue = value_or_register(Dest, Registers),
|
||||
{ Ip + 1, Registers, Queue, lists:append(OtherQueue, [NewValue]), 1 }
|
||||
end.
|
||||
|
||||
start()
|
||||
-> io:fwrite("~p~n", [ assemble("set a 1
|
||||
add a 2
|
||||
mul a a
|
||||
mod a 5
|
||||
snd a
|
||||
set a 0
|
||||
rcv a
|
||||
jgz a -1
|
||||
set a 1
|
||||
jgz a -2") ]),
|
||||
Instructions = "set i 31
|
||||
set a 1
|
||||
mul p 17
|
||||
jgz p p
|
||||
mul a 2
|
||||
add i -1
|
||||
jgz i -2
|
||||
add a -1
|
||||
set i 127
|
||||
set p 952
|
||||
mul p 8505
|
||||
mod p a
|
||||
mul p 129749
|
||||
add p 12345
|
||||
mod p a
|
||||
set b p
|
||||
mod b 10000
|
||||
snd b
|
||||
add i -1
|
||||
jgz i -9
|
||||
jgz a 3
|
||||
rcv b
|
||||
jgz b -1
|
||||
set f 0
|
||||
set i 126
|
||||
rcv a
|
||||
rcv b
|
||||
set p a
|
||||
mul p -1
|
||||
add p b
|
||||
jgz p 4
|
||||
snd a
|
||||
set a b
|
||||
jgz 1 3
|
||||
snd b
|
||||
set f 1
|
||||
add i -1
|
||||
jgz i -11
|
||||
snd a
|
||||
jgz f -16
|
||||
jgz a -19",
|
||||
io:fwrite("~p~n", [ assemble(Instructions) ]),
|
||||
io:fwrite("~p~n", [ assemble2("snd 1
|
||||
snd 2
|
||||
snd p
|
||||
rcv a
|
||||
rcv b
|
||||
rcv c
|
||||
rcv d") ]),
|
||||
io:fwrite("~p~n", [ assemble2(Instructions) ]).
|
Loading…
Reference in New Issue