From 73a3e50ad5a2542c4419b1c9a5931c0b085a6daa Mon Sep 17 00:00:00 2001 From: Caleb Webber Date: Thu, 6 Mar 2025 23:12:15 -0500 Subject: [PATCH] create Euler.Combinatorics.Permutations --- lib/euler/combinatorics/permutations.ex | 22 ++++++++++++++++++++++ solutions/24/solution.exs | 15 +-------------- 2 files changed, 23 insertions(+), 14 deletions(-) create mode 100644 lib/euler/combinatorics/permutations.ex diff --git a/lib/euler/combinatorics/permutations.ex b/lib/euler/combinatorics/permutations.ex new file mode 100644 index 0000000..d76e9f5 --- /dev/null +++ b/lib/euler/combinatorics/permutations.ex @@ -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 + diff --git a/solutions/24/solution.exs b/solutions/24/solution.exs index d90632a..a3bc2c2 100644 --- a/solutions/24/solution.exs +++ b/solutions/24/solution.exs @@ -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()