-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(HIO) :: {shortest_paths, gleam@dict:dict(HIO, integer()), gleam@dict:dict(HIO, HIO)}. -type all_shortest_paths(HIP) :: {all_shortest_paths, gleam@dict:dict(HIP, integer()), gleam@dict:dict(HIP, list(HIP))}. -file("/Users/liteyear/Programming/gleam-dijkstra/src/dijkstra.gleam", 201). -spec do_dijkstra( fun((HJG) -> gleam@dict:dict(HJG, integer())), gleam@dict:dict(HJG, integer()), gleam@dict:dict(HJG, HJG), gleamy@pairing_heap:heap({HJG, integer()}) ) -> shortest_paths(HJG). 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 => 208}) 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 => 211}) 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", 192). -spec dijkstra(fun((HJD) -> gleam@dict:dict(HJD, integer())), HJD) -> shortest_paths(HJD). 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", 231). -spec has_path_to(shortest_paths(HJM), HJM) -> boolean(). has_path_to(Paths, Dest) -> gleam@dict:has_key(erlang:element(2, Paths), Dest). -file("/Users/liteyear/Programming/gleam-dijkstra/src/dijkstra.gleam", 246). -spec do_shortest_path(gleam@dict:dict(HJU, HJU), HJU) -> list(HJU). 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", 239). -spec shortest_path(shortest_paths(HJP), HJP) -> {list(HJP), 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 => 242}) end, {lists:reverse(Path), Dist}. -file("/Users/liteyear/Programming/gleam-dijkstra/src/dijkstra.gleam", 268). -spec do_dijkstra_all( fun((HJZ) -> gleam@dict:dict(HJZ, integer())), gleam@dict:dict(HJZ, integer()), gleam@dict:dict(HJZ, list(HJZ)), gleamy@pairing_heap:heap({HJZ, integer()}) ) -> all_shortest_paths(HJZ). 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 => 275}) 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 => 278}) 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 => 286} ) 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", 259). -spec dijkstra_all(fun((HJW) -> gleam@dict:dict(HJW, integer())), HJW) -> all_shortest_paths(HJW). 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", 307). -spec do_shortest_paths(gleam@dict:dict(HKJ, list(HKJ)), list(HKJ), HKJ) -> list(list(HKJ)). 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", 300). -spec shortest_paths(all_shortest_paths(HKF), HKF) -> {list(list(HKF)), 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 => 303}) end, {Paths, Dist}.