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

73 lines
2.7 KiB
Erlang

-module(day19).
-export([start/0]).
find_start_col([Head|_Tail], Index)
when Head == "|" -> Index;
find_start_col([_Head|Tail], Index)
-> find_start_col(Tail, Index + 1).
map_input(InputList)
-> map_input(InputList, dict:new(), 0).
map_input([], Maze, _Row)
-> Maze;
map_input([Head|Tail], Maze, Row)
-> NewMaze = map_row(re:split(string:chomp(Head), ""), Maze, 0, Row),
map_input(Tail, NewMaze, Row + 1).
map_row([], Maze, _Col, _Row)
-> Maze;
map_row([Head|Tail], Maze, Col, Row)
-> map_row(Tail, dict:store({ Col, Row }, Head, Maze), Col + 1, Row).
trace_maze(Maze, X, Y, Marked, VisitedChars, Steps, DeltaX, DeltaY)
-> Key = { X, Y },
Marked2 = dict:store(Key, 1, Marked),
Value = dict:fetch(Key, Maze),
if Value >= <<"A">>, Value =< <<"Z">> ->
Terminal = is_terminal(Maze, X, Y, Marked2, DeltaX, DeltaY),
if Terminal -> { VisitedChars, Steps };
true -> trace_maze(Maze, X + DeltaX, Y + DeltaY, Marked2, lists:append(VisitedChars, [Value]), Steps + 1, DeltaX, DeltaY)
end;
Value == <<"+">> ->
{ NewDeltaX, NewDeltaY } = find_new_direction(Maze, X, Y, Marked2),
trace_maze(Maze, X + NewDeltaX, Y + NewDeltaY, Marked, VisitedChars, Steps + 1, NewDeltaX, NewDeltaY);
true ->
trace_maze(Maze, X + DeltaX, Y + DeltaY, Marked2, VisitedChars, Steps + 1, DeltaX, DeltaY)
end.
is_terminal(Maze, X, Y, Marked, DeltaX, DeltaY)
-> NextVal = dict:fetch({ X + DeltaX, Y + DeltaY }, Maze),
NextVal == <<" ">>.
find_new_direction(Maze, X, Y, Marked)
-> NorthVal = get_new_direction_val(Maze, X, Y - 1, Marked, <<"|">>),
SouthVal = get_new_direction_val(Maze, X, Y + 1, Marked, <<"|">>),
EastVal = get_new_direction_val(Maze, X + 1, Y, Marked, <<"-">>),
WestVal = get_new_direction_val(Maze, X - 1, Y, Marked, <<"-">>),
if NorthVal -> { 0, -1 };
SouthVal -> { 0, 1 };
EastVal -> { 1, 0 };
WestVal -> { -1, 0 }
end.
get_new_direction_val(Maze, X, Y, Marked, DesiredChar)
-> Key = { X, Y },
HasKey = dict:is_key(Key, Marked),
if HasKey ->
IsMarked = dict:fetch(Key, Marked),
if IsMarked == 1 -> false;
true ->
Piece = dict:fetch(Key, Maze),
Piece == DesiredChar
end;
true -> false
end.
start()
-> { ok, File } = file:read_file("input"),
InputList = re:split(unicode:characters_to_list(string:chomp(File)), "\n"),
Maze = map_input(InputList),
Marked = dict:fold(fun(Key, _Value, Acc) -> dict:store(Key, 0, Acc) end, dict:new(), Maze),
io:fwrite("~p~n", [trace_maze(Maze, 157, 0, Marked, [], 1, 0, 1)]).