Skip to main content

src/twister@property.erl

-module(twister@property).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src\\twister\\property.gleam").
-export([get_fixed_points/1, bijection_for_length/1]).

-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.

?MODULEDOC(
    " Module containing functions to test for properties of a given `Permutation`.\n"
    " \n"
    " ## Note\n"
    " These are something of an afterthought, and not the use case I wrote this library for;\n"
    " as such, take care when using them, since they're not very well documented or extensively\n"
    " tested.\n"
    " \n"
).

-file("src\\twister\\property.gleam", 20).
?DOC(
    " Given a Permutation, get which elements are unchanged.\n"
    " \n"
    " That is, the elements of the list of indices where their index equals their value.\n"
    " \n"
    " The output is a `List` of indices which do not change when a Permutation is performed.\n"
).
-spec get_fixed_points(twister:permutation()) -> list(integer()).
get_fixed_points(Perm) ->
    _pipe = erlang:element(4, Perm),
    _pipe@1 = lists:reverse(_pipe),
    _pipe@2 = gleam@list:index_map(_pipe@1, fun(A, B) -> {A, B} end),
    gleam@list:filter_map(
        _pipe@2,
        fun(C) -> case erlang:element(1, C) =:= erlang:element(2, C) of
                true ->
                    {ok, erlang:element(1, C)};

                false ->
                    {error, nil}
            end end
    ).

-file("src\\twister\\property.gleam", 43).
?DOC(
    " Given a Permutation, check up to what length of input it is a bijection.\n"
    " \n"
    " For a Permutation to be a bijection for a given length `n`, the internal `List` of indices\n"
    " must have a length at least `n + 1`, as well as contain all of the integers smaller than\n"
    " `n` at least once.\n"
    " \n"
    " This way, it is guaranteed to be possible to reverse the permutation given its output;\n"
    " if those requirements are not satisfied, some elements of the original `List` that was\n"
    " permuted will be dropped, and not present in the output, making reversing the operation\n"
    " impossible.\n"
).
-spec bijection_for_length(twister:permutation()) -> integer().
bijection_for_length(Perm) ->
    _pipe = erlang:element(4, Perm),
    _pipe@1 = gleam@set:from_list(_pipe),
    _pipe@2 = gleam@set:to_list(_pipe@1),
    _pipe@3 = gleam@list:sort(_pipe@2, fun gleam@int:compare/2),
    gleam@list:fold_until(_pipe@3, 0, fun(Acc, I) -> case I =:= Acc of
                true ->
                    {continue, Acc + 1};

                false ->
                    {stop, Acc}
            end end).