-module(hyphenation@internal@patterns). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([get_pattern_score/2, new_patterns/0, insert_reference/2, parse_reference/1, new/1, hyphenate/1, read_patterns/1, from_codegen/1, update_score/3, conseq_sublist/1, process_input/2, process/2]). -export_type([input/0, reference_/0, pattern/1, patterns/0]). -opaque input() :: input. -opaque reference_() :: reference. -type pattern(FYQ) :: {pattern, list(binary()), list(integer())} | {gleam_phantom, FYQ}. -type patterns() :: {patterns, list({list(binary()), list(integer())})}. -spec get_pattern_score(patterns(), list(binary())) -> {ok, list(integer())} | {error, nil}. get_pattern_score(Ps, P) -> {patterns, Ls} = Ps, gleam@list:key_find(Ls, P). -spec new_patterns() -> patterns(). new_patterns() -> {patterns, [{[], []}]}. -spec insert_reference(patterns(), pattern(any())) -> patterns(). insert_reference(Ps, P) -> Ref = {erlang:element(2, P), erlang:element(3, P)}, {patterns, Ls} = Ps, {patterns, [Ref | Ls]}. -spec score_reference(binary()) -> list(integer()). score_reference(S) -> case gleam@string:pop_grapheme(S) of {error, nil} -> []; {ok, {X, Xs}} -> case gleam@int:parse(X) of {error, nil} -> [0 | score_reference(Xs)]; {ok, N} -> case gleam@string:pop_grapheme(Xs) of {error, nil} -> [N]; {ok, {_, Ys}} -> [N | score_reference(Ys)] end end end. -spec parse_reference(binary()) -> pattern(reference_()). parse_reference(S) -> Is_not_digit = fun(X) -> _pipe = X, _pipe@1 = gleam@int:parse(_pipe), gleam@result:is_error(_pipe@1) end, New_s = begin _pipe@2 = S, _pipe@3 = gleam@string:to_graphemes(_pipe@2), gleam@list:filter(_pipe@3, Is_not_digit) end, {pattern, New_s, score_reference(S)}. -spec new(binary()) -> pattern(input()). new(S) -> New_s = gleam@string:to_graphemes(S), L = gleam@list:length(New_s), Empty_score = gleam@list:repeat(0, L + 1), {pattern, New_s, Empty_score}. -spec do_hyphenate(list({binary(), integer()}), list(binary())) -> list(binary()). do_hyphenate(Ls, Acc) -> Extract_string = fun(List) -> _pipe = List, _pipe@1 = gleam@list:map(_pipe, fun(T) -> erlang:element(1, T) end), gleam@string:concat(_pipe@1) end, {Head, New_ls} = case Ls of [] -> {{<<""/utf8>>, 0}, []}; [X | Xs] -> case gleam@int:is_odd(erlang:element(2, X)) of true -> {X, Xs}; false -> {{<<""/utf8>>, 0}, [X | Xs]} end end, Split = gleam@list:split_while( New_ls, fun(T@1) -> gleam@int:is_even(erlang:element(2, T@1)) end ), case Split of {[], Rest} -> case Rest of [] -> gleam@list:append(Acc, [erlang:element(1, Head)]); [X@1 | Xs@1] -> case gleam@int:is_odd(erlang:element(2, Head)) of true -> do_hyphenate( [X@1 | Xs@1], gleam@list:append( Acc, [erlang:element(1, Head)] ) ); false -> do_hyphenate( Xs@1, gleam@list:append( Acc, [<<(erlang:element(1, Head))/binary, (erlang:element(1, X@1))/binary>>] ) ) end end; {Syllable, []} -> gleam@list:append( Acc, [<<(erlang:element(1, Head))/binary, (Extract_string(Syllable))/binary>>] ); {Syllable@1, Rest@1} -> do_hyphenate( Rest@1, gleam@list:append( Acc, [<<(erlang:element(1, Head))/binary, (Extract_string(Syllable@1))/binary>>] ) ) end. -spec hyphenate(list({binary(), integer()})) -> list(binary()). hyphenate(Ls) -> do_hyphenate(Ls, []). -spec read_patterns(binary()) -> {ok, patterns()} | {error, simplifile:file_error()}. read_patterns(File) -> gleam@result:map( simplifile:read(File), fun(Patterns_str) -> _pipe = Patterns_str, _pipe@1 = gleam@string:split(_pipe, <<"\n"/utf8>>), _pipe@2 = gleam@list:map(_pipe@1, fun parse_reference/1), gleam@list:fold(_pipe@2, new_patterns(), fun insert_reference/2) end ). -spec from_codegen(list(binary())) -> patterns(). from_codegen(Codegen) -> _pipe = Codegen, _pipe@1 = gleam@list:map(_pipe, fun parse_reference/1), gleam@list:fold(_pipe@1, new_patterns(), fun insert_reference/2). -spec update_score(list(integer()), list(integer()), integer()) -> list(integer()). update_score(Old, New, Padding) -> Pad_left_new = gleam@list:append(gleam@list:repeat(0, Padding), New), Pad_right = gleam@list:repeat( 0, gleam@list:length(Old) - gleam@list:length(Pad_left_new) ), Padded_new = gleam@list:append(Pad_left_new, Pad_right), gleam@list:map2(Old, Padded_new, fun gleam@int:max/2). -spec do_conseq_sublist(list(FZU)) -> list(list(FZU)). do_conseq_sublist(L) -> _pipe = L, gleam@list:index_map(_pipe, fun(_, I) -> gleam@list:take(L, I + 1) end). -spec conseq_sublist(list(FZQ)) -> list({integer(), list(FZQ)}). conseq_sublist(L) -> _pipe = L, _pipe@3 = gleam@list:index_map( _pipe, fun(_, I) -> _pipe@1 = gleam@list:drop(L, I), _pipe@2 = do_conseq_sublist(_pipe@1), gleam@list:map(_pipe@2, fun(Subl) -> {I, Subl} end) end ), gleam@list:concat(_pipe@3). -spec process_input(pattern(input()), patterns()) -> list(integer()). process_input(Inp, Patterns) -> Subs = begin _pipe = erlang:element(2, Inp), conseq_sublist(_pipe) end, _pipe@1 = Subs, gleam@list:fold( _pipe@1, erlang:element(3, Inp), fun(Old_score, Ind_substring) -> case get_pattern_score(Patterns, erlang:element(2, Ind_substring)) of {ok, New_score} -> update_score( Old_score, New_score, erlang:element(1, Ind_substring) ); {error, nil} -> Old_score end end ). -spec process(binary(), patterns()) -> list(binary()). process(S, Ps) -> Pattern = begin _pipe = S, new(_pipe) end, Res_score = process_input(Pattern, Ps), hyphenate(gleam@list:zip(erlang:element(2, Pattern), Res_score)).