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

69 lines
3.1 KiB
Erlang

-module(day16).
-export([start/0]).
dance([], Registers)
-> Registers;
dance([Head|Tail], Registers)
-> Instr = string:slice(Head, 0, 1),
Args = string:slice(Head, 1),
NewRegisters = process_instruction(Instr, Args, Registers),
dance(Tail, NewRegisters).
process_instruction(Instr, Args, Registers)
when Instr == <<"s">> -> Len = string:length(Registers),
{ Count, _ } = string:to_integer(Args),
Index = Len - Count,
First = string:slice(Registers, Index),
Second = string:slice(Registers, 0, Index),
string:concat(First, Second);
process_instruction(Instr, Args, Registers)
when Instr == <<"x">> -> [FirstRegister|Rest] = re:split(Args, "/"),
[SecondRegister|_] = Rest,
{ FirstIndex, _ } = string:to_integer(FirstRegister),
{ SecondIndex, _ } = string:to_integer(SecondRegister),
swap_registers(FirstIndex, SecondIndex, Registers);
process_instruction(Instr, Args, Registers)
when Instr == <<"p">> -> [FirstRegister|Rest] = re:split(Args, "/"),
[SecondRegister|_] = Rest,
IndexA = char_index(FirstRegister, Registers),
IndexB = char_index(SecondRegister, Registers),
swap_registers(IndexA, IndexB, Registers).
char_index(Char, String)
-> StrLen = string:length(String),
StrLen - string:length(string:find(String, Char)).
find_char_index(Index)
when Index == nomatch -> 0;
find_char_index(Index)
-> Index.
swap_registers(A, B, Registers)
when B < A -> swap_registers(B, A, Registers);
swap_registers(A, B, Registers)
-> RegisterList = list_to_tuple(Registers),
ValueA = element(A + 1, RegisterList),
ValueB = element(B + 1, RegisterList),
tuple_to_list(setelement(B + 1, setelement(A + 1, RegisterList, ValueB), ValueA)).
dance_countdown(Steps, Instructions, Registers)
-> dance_countdown(Steps, Instructions, Registers, Steps, []).
dance_countdown(Steps, _Instructions, Registers, _OriginalSteps, _PreviousSteps)
when Steps == 0 -> Registers;
dance_countdown(Steps, Instructions, Registers, OriginalSteps, PreviousSteps)
-> CurrentRegisters = dance(Instructions, Registers),
Found = lists:any(fun(X) -> string:equal(X, CurrentRegisters) end, PreviousSteps),
if Found -> Index = OriginalSteps rem length(PreviousSteps),
lists:nth(Index, PreviousSteps);
true -> dance_countdown(Steps - 1, Instructions, CurrentRegisters, OriginalSteps, lists:append(PreviousSteps, [CurrentRegisters]))
end.
start()
-> SampleInstructions = re:split("s1,x3/4,pe/b", ","),
io:fwrite("~p~n", [dance(SampleInstructions, "abcde")]),
{ ok, File } = file:read_file("input"),
InputInstructions = re:split(unicode:characters_to_list(string:chomp(File)), ","),
io:fwrite("~p~n", [dance(InputInstructions, "abcdefghijklmnop")]),
io:fwrite("~p~n", [dance_countdown(1000000000, InputInstructions, "abcdefghijklmnop")]).