-module(integer_complexity). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([a000792/1, get_complexities_up_to/2, get_expressions_up_to/2, get_complexity/2, get_expression/2, new_cache/0]). -export_type([complexities_cache/0, complexity_data/0, derived_expression/0]). -opaque complexities_cache() :: {complexities_cache, gary:erlang_array(complexity_data()), integer()}. -type complexity_data() :: {complexity_data, integer(), derived_expression()}. -type derived_expression() :: {derived_add, derived_expression(), derived_expression()} | {derived_multiply, derived_expression(), derived_expression()} | {derived, integer()} | derived_one. -spec a000792_rec(integer(), integer()) -> integer(). a000792_rec(N, Result) -> case (N >= 5) orelse (N =:= 3) of true -> a000792_rec(N - 3, Result * 3); false -> erlang:'bsl'(Result, N div 2) end. -spec a000792(integer()) -> integer(). a000792(N) -> a000792_rec(N, 1). -spec calc_t(integer(), integer(), integer()) -> integer(). calc_t(T, Target, Index) -> case (a000792(T) + a000792(Target - T)) < Index of true -> calc_t(T - 1, Target, Index); false -> T end. -spec construct_expression(complexities_cache(), derived_expression()) -> integer_complexity@expression:expression(). construct_expression(Cache, Derived_expression) -> case Derived_expression of derived_one -> one; {derived_add, Lhs, Rhs} -> {add, construct_expression(Cache, Lhs), construct_expression(Cache, Rhs)}; {derived_multiply, Lhs@1, Rhs@1} -> {multiply, construct_expression(Cache, Lhs@1), construct_expression(Cache, Rhs@1)}; {derived, N} -> _assert_subject = integer_complexity@internal@array:get( erlang:element(2, Cache), N ), {ok, Data} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"integer_complexity"/utf8>>, function => <<"construct_expression"/utf8>>, line => 336}) end, construct_expression(Cache, erlang:element(3, Data)) end. -spec sums( integer(), integer(), integer(), gary:erlang_array(complexity_data()) ) -> gary:erlang_array(complexity_data()). sums(M, Max, N, Complexity) -> gleam@bool:guard( M > Max, Complexity, fun() -> Complexity_m = begin _pipe = integer_complexity@internal@array:get(Complexity, M), _pipe@1 = gleam@result:map( _pipe, fun(X) -> erlang:element(2, X) end ), gleam@result:unwrap(_pipe@1, 2147483647) end, Complexity_n = begin _pipe@2 = integer_complexity@internal@array:get(Complexity, N), _pipe@3 = gleam@result:map( _pipe@2, fun(X@1) -> erlang:element(2, X@1) end ), gleam@result:unwrap(_pipe@3, 2147483647) end, _assert_subject = begin _pipe@4 = integer_complexity@internal@array:get( Complexity, N - M ), _pipe@5 = gleam@result:map( _pipe@4, fun(X@2) -> erlang:element(2, X@2) end ), gleam@result:unwrap(_pipe@5, 2147483647) end, Complexity_n_m = case _assert_subject of _ -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"integer_complexity"/utf8>>, function => <<"sums"/utf8>>, line => 239}) end, Sum_value = Complexity_m + Complexity_n_m, _assert_subject@1 = case Sum_value < Complexity_n of true -> integer_complexity@internal@array:set( Complexity, N, {complexity_data, Sum_value, {derived_add, {derived, M}, {derived, N - M}}} ); false -> {ok, Complexity} end, {ok, Updated_complexity} = case _assert_subject@1 of {ok, _} -> _assert_subject@1; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@1, module => <<"integer_complexity"/utf8>>, function => <<"sums"/utf8>>, line => 246}) end, sums(M + 1, Max, N, Updated_complexity) end ). -spec products( integer(), integer(), integer(), gary:erlang_array(complexity_data()) ) -> gary:erlang_array(complexity_data()). products(K, Max, N, Complexity) -> gleam@bool:guard( K > Max, Complexity, fun() -> Complexity_k = begin _pipe = integer_complexity@internal@array:get(Complexity, K), _pipe@1 = gleam@result:map( _pipe, fun(X) -> erlang:element(2, X) end ), gleam@result:unwrap(_pipe@1, 2147483647) end, Complexity_n = begin _pipe@2 = integer_complexity@internal@array:get(Complexity, N), _pipe@3 = gleam@result:map( _pipe@2, fun(X@1) -> erlang:element(2, X@1) end ), gleam@result:unwrap(_pipe@3, 2147483647) end, Complexity_k_n = integer_complexity@internal@array:get( Complexity, K * N ), Prod_value = Complexity_k + Complexity_n, _assert_subject = case Complexity_k_n of {error, _} -> integer_complexity@internal@array:set( Complexity, K * N, {complexity_data, Prod_value, {derived_multiply, {derived, K}, {derived, N}}} ); {ok, {complexity_data, K_n_value, _}} when Prod_value < K_n_value -> integer_complexity@internal@array:set( Complexity, K * N, {complexity_data, Prod_value, {derived_multiply, {derived, K}, {derived, N}}} ); _ -> {ok, Complexity} end, {ok, Updated_complexity} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"integer_complexity"/utf8>>, function => <<"products"/utf8>>, line => 281}) end, products(K + 1, Max, N, Updated_complexity) end ). -spec complexity_rec(integer(), integer(), gary:erlang_array(complexity_data())) -> gary:erlang_array(complexity_data()). complexity_rec(N, Max_integer, Complexity_array) -> gleam@bool:lazy_guard( N > Max_integer, fun() -> Complexity_array end, fun() -> Usual_best_value = begin _pipe = integer_complexity@internal@array:get( Complexity_array, N - 1 ), _pipe@1 = gleam@result:map( _pipe, fun(X) -> erlang:element(2, X) end ), _pipe@2 = gleam@result:unwrap(_pipe@1, 2147483647), gleam@int:add(_pipe@2, 1) end, Complexity_n = begin _pipe@3 = integer_complexity@internal@array:get( Complexity_array, N ), _pipe@4 = gleam@result:map( _pipe@3, fun(X@1) -> erlang:element(2, X@1) end ), gleam@result:unwrap(_pipe@4, 2147483647) end, _assert_subject = case Usual_best_value < Complexity_n of true -> integer_complexity@internal@array:set( Complexity_array, N, {complexity_data, Usual_best_value, {derived_add, {derived, N - 1}, derived_one}} ); false -> {ok, Complexity_array} end, {ok, Complexity} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"integer_complexity"/utf8>>, function => <<"complexity_rec"/utf8>>, line => 180}) end, _assert_subject@1 = begin _pipe@5 = integer_complexity@internal@array:get( Complexity, N - 1 ), _pipe@6 = gleam@result:map( _pipe@5, fun(X@2) -> erlang:element(2, X@2) end ), gleam@result:unwrap(_pipe@6, 2147483647) end, Target = case _assert_subject@1 of _ -> _assert_subject@1; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@1, module => <<"integer_complexity"/utf8>>, function => <<"complexity_rec"/utf8>>, line => 191}) end, T = calc_t(Target div 2, Target, N), K_max = a000792(T), Complexity@1 = sums(6, K_max, N, Complexity), Complexity@2 = products(2, N, N, Complexity@1), complexity_rec(N + 1, Max_integer, Complexity@2) end ). -spec extend_complexity_list(integer(), complexities_cache()) -> {ok, gary:erlang_array(complexity_data())} | {error, nil}. extend_complexity_list(Max_integer, Cache) -> gleam@bool:guard( Max_integer < 0, {error, nil}, fun() -> Extension_start = erlang:element(3, Cache), Complexity_array = erlang:element(2, Cache), {ok, complexity_rec( gleam@int:max(2, Extension_start + 1), Max_integer, Complexity_array )} end ). -spec get_complexity_data_up_to(complexities_cache(), integer()) -> {complexities_cache(), list(complexity_data())}. get_complexity_data_up_to(Cache, Integer) -> case Integer =< erlang:element(3, Cache) of true -> List = begin _pipe = integer_complexity@internal@array:to_list( erlang:element(2, Cache) ), _pipe@1 = gleam@list:drop(_pipe, 1), gleam@list:take(_pipe@1, Integer) end, {Cache, List}; false -> _assert_subject = extend_complexity_list(Integer, Cache), {ok, New_cache} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"integer_complexity"/utf8>>, function => <<"get_complexity_data_up_to"/utf8>>, line => 86}) end, get_complexity_data_up_to( {complexities_cache, New_cache, Integer}, Integer ) end. -spec get_complexities_up_to(complexities_cache(), integer()) -> {ok, {complexities_cache(), list(integer())}} | {error, nil}. get_complexities_up_to(Cache, Integer) -> gleam@bool:guard( Integer =< 0, {error, nil}, fun() -> case get_complexity_data_up_to(Cache, Integer) of {Cache@1, Data} -> {ok, {Cache@1, gleam@list:map( Data, fun(X) -> erlang:element(2, X) end )}} end end ). -spec get_expressions_up_to(complexities_cache(), integer()) -> {ok, {complexities_cache(), list(integer_complexity@expression:expression())}} | {error, nil}. get_expressions_up_to(Cache, Integer) -> gleam@bool:guard( Integer =< 0, {error, nil}, fun() -> case get_complexity_data_up_to(Cache, Integer) of {Cache@1, Data} -> {ok, {Cache@1, gleam@list:map( Data, fun(X) -> construct_expression( Cache@1, erlang:element(3, X) ) end )}} end end ). -spec get_complexity_data(complexities_cache(), integer()) -> {complexities_cache(), complexity_data()}. get_complexity_data(Cache, Integer) -> case integer_complexity@internal@array:get( erlang:element(2, Cache), Integer ) of {ok, Data} when Integer =< erlang:element(3, Cache) -> {Cache, Data}; _ -> _assert_subject = extend_complexity_list(Integer, Cache), {ok, New_cache} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"integer_complexity"/utf8>>, function => <<"get_complexity_data"/utf8>>, line => 128}) end, get_complexity_data( {complexities_cache, New_cache, Integer}, Integer ) end. -spec get_complexity(complexities_cache(), integer()) -> {complexities_cache(), integer()}. get_complexity(Cache, Integer) -> gleam@bool:guard( Integer =:= 0, {Cache, 0}, fun() -> case get_complexity_data(Cache, gleam@int:absolute_value(Integer)) of {Cache@1, Data} -> {Cache@1, erlang:element(2, Data)} end end ). -spec get_expression(complexities_cache(), integer()) -> {ok, {complexities_cache(), integer_complexity@expression:expression()}} | {error, nil}. get_expression(Cache, Integer) -> gleam@bool:guard( Integer =:= 0, {error, nil}, fun() -> case get_complexity_data(Cache, gleam@int:absolute_value(Integer)) of {Cache@1, Data} -> {ok, {Cache@1, construct_expression( Cache@1, erlang:element(3, Data) )}} end end ). -spec new_cache() -> complexities_cache(). new_cache() -> Array = begin _pipe = [0, 1], _pipe@1 = gleam@list:map( _pipe, fun(_capture) -> {complexity_data, _capture, derived_one} end ), integer_complexity@internal@array:from_list( _pipe@1, {complexity_data, 0, derived_one} ) end, {complexities_cache, Array, 0}.