22 lines
746 B
Elixir
22 lines
746 B
Elixir
defmodule Euler.Combinatorics.Permutations do
|
|
defp index_at(_, 0, acc), do: acc |> Enum.reverse()
|
|
defp index_at(n, remaining, acc) do
|
|
blk_size = Euler.Algebra.fact(remaining - 1)
|
|
index_at(rem(n, blk_size), remaining - 1, [ div(n, blk_size) | acc ])
|
|
end
|
|
|
|
@doc """
|
|
Generates the n-th indexed permutation in the lexicographically ordered list of `remaining` digits.
|
|
"""
|
|
def index_at(n, remaining) do
|
|
index_at(n, remaining, [])
|
|
|> translate(remaining)
|
|
end
|
|
|
|
defp translate(a, n) when is_number(n), do: translate(a, (0..(n-1)) |> Enum.to_list)
|
|
defp translate(_, []), do: []
|
|
defp translate([next | rest], allowed) do
|
|
[ (allowed |> Enum.at(next)) | translate(rest, allowed |> List.delete_at(next)) ]
|
|
end
|
|
end
|
|
|