create Euler.Combinatorics.Permutations

This commit is contained in:
Caleb Webber 2025-03-06 23:12:15 -05:00
parent 9c83edc929
commit 73a3e50ad5
2 changed files with 23 additions and 14 deletions

View file

@ -0,0 +1,22 @@
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

View file

@ -1,19 +1,6 @@
defmodule Permutations do alias Euler.Combinatorics.Permutations
def index_at(_, 0), do: []
def index_at(n, remaining) do
blk_size = Euler.Algebra.fact(remaining - 1)
[ div(n, blk_size) | index_at(rem(n, blk_size), remaining - 1) ]
end
def translate(a, n) when is_number(n), do: translate(a, (0..(n-1)) |> Enum.to_list)
def translate(_, []), do: []
def translate([next | rest], allowed) do
[ (allowed |> Enum.at(next)) | translate(rest, allowed |> List.delete_at(next)) ]
end
end
# subtract one to get the 1 millionth permutation (bc it's zero indexed # subtract one to get the 1 millionth permutation (bc it's zero indexed
Permutations.index_at(1_000_000 - 1, 10) Permutations.index_at(1_000_000 - 1, 10)
|> Permutations.translate(0..9 |> Enum.to_list)
|> Enum.join("") |> Enum.join("")
|> IO.puts() |> IO.puts()