-3

How one might write a function (in Python) that:

If we take all the permutations for A, B and C: ABC, ACB, BAC, BCA, CAB, CBA

The function would take an index and return the permutation for that index.

E.g. F("ABC", 4) would return "BCA"

It should run in a reasonable time for very large permutation sets.

matt.whitby
  • 47
  • 10
  • Does it need to run in reasonable time for very large indices too? – Samwise Jul 01 '21 at 19:13
  • 2
    Hello and welcome to stackoverflow! Could you share what you have tried so far? – Giovanni Rescia Jul 01 '21 at 19:15
  • What is the ordering of the permutations? Is it always lexicographical? – Captain Trojan Jul 01 '21 at 19:16
  • See [`itertools.permutations`](https://docs.python.org/3/library/itertools.html#itertools.permutations) as a starting point but probably not for "very large permutation sets". – not_speshal Jul 01 '21 at 19:17
  • The book "Constructive Combinatorics" by Stanton and White contains many such algorithms. It gives Pascal-like pseudocode which is easy enough to translate into Python. As a general resource for all such questions, I highly recommend it. – John Coleman Jul 01 '21 at 19:22

1 Answers1

0

You could parse/filter the results of itertools.permutations(), because generators can't directly be indexed. A function like this would do it:

from itertools import permutations

def nth_permutation(items, n):
    i = 0
    perms = permutations(items)
    try:
        next_perm = next(perms)
        while i < n:
           next_perm = next(perms)
           i += 1
    except StopIteration:
        # implement error behavior here, if n > number of permutations. 
        # For now we just return the default value, None
        # you might instead try throwing an IndexError
        return None
    return next_perm

(note that the permutation with index 4 is "CAB" - "BCA" is index 3)

Green Cloak Guy
  • 23,793
  • 4
  • 33
  • 53
  • 1
    "You'd need to parse/filter the results of itertools.permutations()" -- why say that? It is fairly straightforward to find permuation # 345,678,911 of the alphabet without actually generating any more than 1 permutation. – John Coleman Jul 01 '21 at 19:21
  • 2
    You don't need to generate all of the permutations up to the nth one; there is an algorithm to generate the nth permutation directly using factorials, which can be found in the linked duplicate. – kaya3 Jul 01 '21 at 19:21