# TODO: this gets the correct answer for project Euler, but is not correct in the general case. # Figure that out. 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 Permutations.index_at(1_000_000, 10) |> Permutations.translate(0..9 |> Enum.to_list) |> Enum.join("") |> IO.puts() print_permutations = fn n -> (0..(Euler.Algebra.fact(n)-1)) |> Enum.map(fn i -> Permutations.index_at(i, n) |> Permutations.translate(n) |> Enum.join("") |> IO.puts() end) end print_permutations.(5) # 999990 - 2783914056 # 999991 - 2783914065 # 999992 - 2783914506 # 999993 - 2783914560 # 999994 - 2783914605 # 999995 - 2783914650 # 999996 - 2783915046 # 999997 - 2783915064 # 999998 - 2783915406 # 999999 - 2783915460 # 1000000 - 2783915604 # 1000001 - 2783915640 # 1000002 - 2783916045 # 1000003 - 2783916054 # 1000004 - 2783916405 # 1000005 - 2783916450 # 1000006 - 2783916504 # 1000007 - 2783916540 # 1000008 - 2783940156 # 1000009 - 2783940165 # 1000010 - 2783940516 999_990..1_000_010 |> Enum.map(fn i -> n = Permutations.index_at(i, 10) |> Permutations.translate(10) |> Enum.join("") IO.puts("#{i} - #{n}") end)