73 lines
2.7 KiB
Erlang
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)]).
|