-module(glsql@suggest). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/glsql/suggest.gleam"). -export([distance/2, closest/2]). -file("src/glsql/suggest.gleam", 35). -spec step_row(list(binary()), list(integer()), binary(), integer()) -> list(integer()). step_row(B, Prev, Ac, I) -> Start = I + 1, {Row, _} = gleam@list:fold( B, {[Start], Prev}, fun(State, Bc) -> {Acc, Prev_rest} = State, case {Acc, Prev_rest} of {[Left | _], [Diag, Up | Rest]} -> Cost = case Ac =:= Bc of true -> 0; false -> 1 end, Best = gleam@int:min( gleam@int:min(Left + 1, Up + 1), Diag + Cost ), {[Best | Acc], [Up | Rest]}; {_, _} -> State end end ), lists:reverse(Row). -file("src/glsql/suggest.gleam", 19). -spec distance(binary(), binary()) -> integer(). distance(A, B) -> A@1 = gleam@string:to_graphemes(A), B@1 = gleam@string:to_graphemes(B), First_row = begin _pipe = gleam@int:range( 0, erlang:length(B@1) + 1, [], fun(Acc, I) -> [I | Acc] end ), lists:reverse(_pipe) end, Final = gleam@list:index_fold( A@1, First_row, fun(Prev, Ac, I@1) -> step_row(B@1, Prev, Ac, I@1) end ), case gleam@list:last(Final) of {ok, D} -> D; {error, nil} -> 0 end. -file("src/glsql/suggest.gleam", 6). -spec closest(binary(), list(binary())) -> gleam@option:option(binary()). closest(Word, Candidates) -> Needle = string:lowercase(Word), Limit = gleam@int:min(2, string:length(Needle) - 1), _pipe = Candidates, _pipe@1 = gleam@list:map( _pipe, fun(C) -> {C, distance(Needle, string:lowercase(C))} end ), _pipe@2 = gleam@list:filter( _pipe@1, fun(Pair) -> erlang:element(2, Pair) =< Limit end ), _pipe@3 = gleam@list:sort( _pipe@2, fun(A, B) -> gleam@int:compare(erlang:element(2, A), erlang:element(2, B)) end ), _pipe@4 = gleam@list:first(_pipe@3), _pipe@5 = gleam@option:from_result(_pipe@4), gleam@option:map(_pipe@5, fun(Pair@1) -> erlang:element(1, Pair@1) end).