Packages

A library for computing integer complexity.

Current section

Files

Jump to
integer_complexity src integer_complexity.erl
Raw

src/integer_complexity.erl

-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}.