1

I need to write a function in c++ or python that gets a string and prints all the options that it can be scrambled. for example - scramble("abc") will print -

abc
acb
bac
bca
cab
cba

Of course it wouldn't be only words that their length is 3.

Daniel Robinson
  • 3,347
  • 2
  • 18
  • 20
oridamari
  • 561
  • 7
  • 12
  • 24

2 Answers2

7

In Python, you can use the handy permutations function from itertools.

from itertools import permutations

def scrambles(word):
    return [''.join(permutation) for permutation in permutations(word)]

Alternatively, here's a recursive permutation algorithm explicitly spelled out:

def permutations(word):

    if len(word) == 1:
        # the word is one letter long, so this is the base case; there is only one permutation
        return [word]

    # recursively get all permutations of the word after its first letter
    subword_perms = permutations(word[1:])

    # insert the first letter at all possible positions in each of the possible permutations of the rest of the letters
    first_letter = word[0]
    perms = []
    for subword_perm in subword_perms:
        for i in range(len(subword_perm)+1):
            perm = subword_perm[:i] + first_letter + subword_perm[i:]

            # test to make sure permutation wasn't already found (which is possible if some letters are duplicated within the word)
            if perm not in perms:
                perms.append(perm)
    return perms
Daniel Robinson
  • 3,347
  • 2
  • 18
  • 20
  • Great! But how does it work? It's a great trick in python but i need to know how the algorithm works. can someone try to write it in c++? – oridamari Jan 21 '15 at 01:34
1

Here's a shorter recursive function to find all permutations of letters in a string:

def gen_perms(n,text):
    if n == 1:
        return {a for a in text}
    temp = {a + b
           for a in text
           for b in gen_perms(n-1,text)}
    return temp

n is the length of the words/sets you want to generate

text is the set of letters you want to use.

I use sets because they have no duplicate entries; only unique elements.

To explain the algorithm, start with the base case of n=1. This special case is dealt with by returning each of the letters.

    if n == 1:
        return {a for a in text}

Example, when n=1, text='yz':

>>> perms = gen_perms(1,'yz')
>>> print len(perms)
2
>>> print sorted(perms)
['y', 'z']

When n=2, we recursively run the function, so think about the base case from above being returned on this line:

           {a + b
           for a in text
           for b in gen_perms(n-1,text)}

and adding each possible letter onto that. I'll rewrite it with the text replaced with the values we entered:

           {a + b
           for a in 'yz'
           for b in ['y','z']}

Hopefully you can see that we would get ['yy', 'yz', 'zy', 'zz'], and we do:

>>> perms = gen_perms(2,'yz')
>>> print len(perms)
4
>>> print sorted(perms)
['yy', 'yz', 'zy', 'zz']

Sets are really nice to use here, because if we change our text to contain repeated letters, they are disregared:

>>> perms = gen_perms(2,'yyyzz')
>>> print len(perms)
4
>>> print sorted(perms)
['yy', 'yz', 'zy', 'zz']