0

I would like to get the Nth element of a permutation list without creating all of the permutations

If I execute perm = permutations(range(3)) I get:

(0, 1, 2) (0, 2, 1) (1, 0, 2) (1, 2, 0) (2, 0, 1) (2, 1, 0)

And I can get the 4th element by doing perm[3] that is (1, 2, 0)

The problem comes when I want to get the 12843175th element of permutations(range(12)) or higher because my computer causes memory error

Is there a more optimal way to obtain this value?

DDela
  • 23
  • 7
  • 1
    Yes. you calculate it yourself, without using the permissions function. It's a mathematical task which requires some thought. It looks like a challenge from some coding site. You should solve it yourself, otherwise, what's the point? – zvone Feb 17 '23 at 07:34

1 Answers1

2

2 approaches to extract a permutation at the needed position:

1) The fastest one: with itertools.islice to return an element at specific offsets:


from itertools import permutations, islice

def get_nth_permuted(rng, pos):
    return next(islice(permutations(rng), pos, None), None)

print(get_nth_permuted(range(40), 72843175))

(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 29, 38, 28, 36, 35, 30, 31, 34, 33, 32, 39, 37)

2) A more straightforward, but much slower is traversing over iterator and capture/yield the value only at the needed position:

from itertools import permutations

def get_nth_permuted(rng, pos):
    return next((v for i, v in enumerate(permutations(rng)) if i == pos), None)

print(get_nth_permuted2(range(40), 72843175))

(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 29, 38, 28, 36, 35, 30, 31, 34, 33, 32, 39, 37)
RomanPerekhrest
  • 88,541
  • 4
  • 65
  • 105