Current section
Files
Jump to
Current section
Files
src/dijkstra.erl
-module(dijkstra).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([dijkstra/2, has_path_to/2, shortest_path/2, dijkstra_all/2, shortest_paths/2]).
-export_type([shortest_paths/1, all_shortest_paths/1]).
-type shortest_paths(IJW) :: {shortest_paths,
gleam@dict:dict(IJW, integer()),
gleam@dict:dict(IJW, IJW)}.
-type all_shortest_paths(IJX) :: {all_shortest_paths,
gleam@dict:dict(IJX, integer()),
gleam@dict:dict(IJX, list(IJX))}.
-file("/Users/liteyear/Programming/gleam-dijkstra/src/dijkstra.gleam", 68).
-spec do_dijkstra(
fun((IKO) -> gleam@dict:dict(IKO, integer())),
gleam@dict:dict(IKO, integer()),
gleam@dict:dict(IKO, IKO),
gleamy@pairing_heap:heap({IKO, integer()})
) -> shortest_paths(IKO).
do_dijkstra(Edges_from, Dist, Pred, Q) ->
case gleamy@priority_queue:is_empty(Q) of
true ->
{shortest_paths, Dist, Pred};
false ->
_assert_subject = gleamy@priority_queue:pop(Q),
{ok, {{U, _}, Q@1}} = case _assert_subject of
{ok, {{_, _}, _}} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
value => _assert_fail,
module => <<"dijkstra"/utf8>>,
function => <<"do_dijkstra"/utf8>>,
line => 75})
end,
{Dist@2, Pred@2, Q@3} = gleam@dict:fold(
Edges_from(U),
{Dist, Pred, Q@1},
fun(Acc, V, Uv_dist) ->
{Dist@1, Pred@1, Q@2} = Acc,
_assert_subject@1 = gleam_stdlib:map_get(Dist@1, U),
{ok, U_dist} = case _assert_subject@1 of
{ok, _} -> _assert_subject@1;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
value => _assert_fail@1,
module => <<"dijkstra"/utf8>>,
function => <<"do_dijkstra"/utf8>>,
line => 78})
end,
Alt = U_dist + Uv_dist,
case gleam_stdlib:map_get(Dist@1, V) of
{ok, V_dist} when Alt >= V_dist ->
Acc;
_ ->
{gleam@dict:insert(Dist@1, V, Alt),
gleam@dict:insert(Pred@1, V, U),
gleamy@priority_queue:push(Q@2, {V, Alt})}
end
end
),
do_dijkstra(Edges_from, Dist@2, Pred@2, Q@3)
end.
-file("/Users/liteyear/Programming/gleam-dijkstra/src/dijkstra.gleam", 59).
-spec dijkstra(fun((IKL) -> gleam@dict:dict(IKL, integer())), IKL) -> shortest_paths(IKL).
dijkstra(Edges_from, Start) ->
Dist = maps:from_list([{Start, 0}]),
Q = gleamy@priority_queue:from_list(
[{Start, 0}],
fun(A, B) ->
gleam@int:compare(erlang:element(2, A), erlang:element(2, B))
end
),
do_dijkstra(Edges_from, Dist, maps:new(), Q).
-file("/Users/liteyear/Programming/gleam-dijkstra/src/dijkstra.gleam", 98).
-spec has_path_to(shortest_paths(IKU), IKU) -> boolean().
has_path_to(Paths, Dest) ->
gleam@dict:has_key(erlang:element(2, Paths), Dest).
-file("/Users/liteyear/Programming/gleam-dijkstra/src/dijkstra.gleam", 113).
-spec do_shortest_path(gleam@dict:dict(ILC, ILC), ILC) -> list(ILC).
do_shortest_path(Predecessors, Curr) ->
case gleam_stdlib:map_get(Predecessors, Curr) of
{error, _} ->
[Curr];
{ok, Pred} ->
[Curr | do_shortest_path(Predecessors, Pred)]
end.
-file("/Users/liteyear/Programming/gleam-dijkstra/src/dijkstra.gleam", 106).
-spec shortest_path(shortest_paths(IKX), IKX) -> {list(IKX), integer()}.
shortest_path(Paths, Dest) ->
Path = do_shortest_path(erlang:element(3, Paths), Dest),
_assert_subject = gleam_stdlib:map_get(erlang:element(2, Paths), Dest),
{ok, Dist} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
value => _assert_fail,
module => <<"dijkstra"/utf8>>,
function => <<"shortest_path"/utf8>>,
line => 109})
end,
{lists:reverse(Path), Dist}.
-file("/Users/liteyear/Programming/gleam-dijkstra/src/dijkstra.gleam", 135).
-spec do_dijkstra_all(
fun((ILH) -> gleam@dict:dict(ILH, integer())),
gleam@dict:dict(ILH, integer()),
gleam@dict:dict(ILH, list(ILH)),
gleamy@pairing_heap:heap({ILH, integer()})
) -> all_shortest_paths(ILH).
do_dijkstra_all(Edges_from, Dist, Pred, Q) ->
case gleamy@priority_queue:is_empty(Q) of
true ->
{all_shortest_paths, Dist, Pred};
false ->
_assert_subject = gleamy@priority_queue:pop(Q),
{ok, {{U, _}, Q@1}} = case _assert_subject of
{ok, {{_, _}, _}} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
value => _assert_fail,
module => <<"dijkstra"/utf8>>,
function => <<"do_dijkstra_all"/utf8>>,
line => 142})
end,
{Dist@2, Pred@2, Q@3} = gleam@dict:fold(
Edges_from(U),
{Dist, Pred, Q@1},
fun(Acc, V, Uv_dist) ->
{Dist@1, Pred@1, Q@2} = Acc,
_assert_subject@1 = gleam_stdlib:map_get(Dist@1, U),
{ok, U_dist} = case _assert_subject@1 of
{ok, _} -> _assert_subject@1;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
value => _assert_fail@1,
module => <<"dijkstra"/utf8>>,
function => <<"do_dijkstra_all"/utf8>>,
line => 145})
end,
Alt = U_dist + Uv_dist,
case gleam_stdlib:map_get(Dist@1, V) of
{ok, V_dist} when Alt > V_dist ->
Acc;
{ok, V_dist@1} when Alt =:= V_dist@1 ->
{Dist@1,
gleam@dict:upsert(Pred@1, V, fun(X) -> case X of
{some, I} ->
[U | I];
_ ->
erlang:error(
#{gleam_error => panic,
message => <<"BUG"/utf8>>,
module => <<"dijkstra"/utf8>>,
function => <<"do_dijkstra_all"/utf8>>,
line => 153}
)
end end),
Q@2};
_ ->
{gleam@dict:insert(Dist@1, V, Alt),
gleam@dict:insert(Pred@1, V, [U]),
gleamy@priority_queue:push(Q@2, {V, Alt})}
end
end
),
do_dijkstra_all(Edges_from, Dist@2, Pred@2, Q@3)
end.
-file("/Users/liteyear/Programming/gleam-dijkstra/src/dijkstra.gleam", 126).
-spec dijkstra_all(fun((ILE) -> gleam@dict:dict(ILE, integer())), ILE) -> all_shortest_paths(ILE).
dijkstra_all(Edges_from, Start) ->
Dist = maps:from_list([{Start, 0}]),
Q = gleamy@priority_queue:from_list(
[{Start, 0}],
fun(A, B) ->
gleam@int:compare(erlang:element(2, A), erlang:element(2, B))
end
),
do_dijkstra_all(Edges_from, Dist, maps:new(), Q).
-file("/Users/liteyear/Programming/gleam-dijkstra/src/dijkstra.gleam", 174).
-spec do_shortest_paths(gleam@dict:dict(ILR, list(ILR)), list(ILR), ILR) -> list(list(ILR)).
do_shortest_paths(Predecessors, Path, Curr) ->
New_path = [Curr | Path],
case gleam_stdlib:map_get(Predecessors, Curr) of
{error, _} ->
[New_path];
{ok, Preds} ->
gleam@list:flat_map(
Preds,
fun(_capture) ->
do_shortest_paths(Predecessors, New_path, _capture)
end
)
end.
-file("/Users/liteyear/Programming/gleam-dijkstra/src/dijkstra.gleam", 167).
-spec shortest_paths(all_shortest_paths(ILN), ILN) -> {list(list(ILN)),
integer()}.
shortest_paths(All_paths, Dest) ->
Paths = do_shortest_paths(erlang:element(3, All_paths), [], Dest),
_assert_subject = gleam_stdlib:map_get(erlang:element(2, All_paths), Dest),
{ok, Dist} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
value => _assert_fail,
module => <<"dijkstra"/utf8>>,
function => <<"shortest_paths"/utf8>>,
line => 170})
end,
{Paths, Dist}.