Packages

Directed and undirected graphs

Current section

Files

Jump to
graph src graph@internal@heap.erl
Raw

src/graph@internal@heap.erl

-module(graph@internal@heap).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([new/1, min/1, add/2, pop_min/1]).
-export_type([heap/1, heap_repr/1]).
-opaque heap(GHV) :: {heap,
heap_repr(GHV),
fun((GHV, GHV) -> gleam@order:order())}.
-type heap_repr(GHW) :: empty | {cons, GHW, list(heap_repr(GHW))}.
-spec new(fun((GHX, GHX) -> gleam@order:order())) -> heap(GHX).
new(Compare) ->
{heap, empty, Compare}.
-spec min(heap(GIH)) -> {ok, GIH} | {error, nil}.
min(Heap) ->
case Heap of
{heap, empty, _} ->
{error, nil};
{heap, {cons, Min, _}, _} ->
{ok, Min}
end.
-spec merge(
heap_repr(GIL),
heap_repr(GIL),
fun((GIL, GIL) -> gleam@order:order())
) -> heap_repr(GIL).
merge(One, Other, Compare) ->
case {One, Other} of
{empty, Res} ->
Res;
{Res, empty} ->
Res;
{{cons, Min_one, Rest_one}, {cons, Min_other, Rest_other}} ->
case Compare(Min_one, Min_other) of
lt ->
{cons, Min_one, [Other | Rest_one]};
eq ->
{cons, Min_one, [Other | Rest_one]};
gt ->
{cons, Min_other, [One | Rest_other]}
end
end.
-spec add(heap(GHZ), GHZ) -> heap(GHZ).
add(Heap, Item) ->
{heap, Heap@1, Compare} = Heap,
Heap@2 = merge(Heap@1, {cons, Item, []}, Compare),
{heap, Heap@2, Compare}.
-spec merge_all(list(heap_repr(GIP)), fun((GIP, GIP) -> gleam@order:order())) -> heap_repr(GIP).
merge_all(Heaps, Compare) ->
case Heaps of
[] ->
empty;
[Heap] ->
Heap;
[One_heap, Other_heap | Heaps@1] ->
_pipe = merge(One_heap, Other_heap, Compare),
merge(_pipe, merge_all(Heaps@1, Compare), Compare)
end.
-spec pop_min(heap(GIC)) -> {ok, {GIC, heap(GIC)}} | {error, nil}.
pop_min(Heap) ->
case Heap of
{heap, empty, _} ->
{error, nil};
{heap, {cons, Min, Rest}, Compare} ->
Remaining = merge_all(Rest, Compare),
{ok, {Min, {heap, Remaining, Compare}}}
end.