create Euler.Combinatorics.Permutations
This commit is contained in:
parent
9c83edc929
commit
73a3e50ad5
2 changed files with 23 additions and 14 deletions
22
lib/euler/combinatorics/permutations.ex
Normal file
22
lib/euler/combinatorics/permutations.ex
Normal 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
|
||||
|
|
@ -1,19 +1,6 @@
|
|||
defmodule Permutations do
|
||||
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
|
||||
alias Euler.Combinatorics.Permutations
|
||||
|
||||
# subtract one to get the 1 millionth permutation (bc it's zero indexed
|
||||
Permutations.index_at(1_000_000 - 1, 10)
|
||||
|> Permutations.translate(0..9 |> Enum.to_list)
|
||||
|> Enum.join("")
|
||||
|> IO.puts()
|
||||
|
|
Loading…
Add table
Reference in a new issue