0

I'm having trouble drawing a recursion tree for the following permutation code:

def permut(array):

    if len(array) == 1:
        return [array]
    res = []
    for permutation in permut(array[1:]):
        print permutation, array
        for i in range(len(array)):
            res.append(permutation[:i] + array[0:1] + permutation[i:])
    return res

Let's say my array is 'mick' then I get the following print outs for permutation and array:

k and ck

ck and ick

kc and ick

ick and mick

I understand it until 'k' and 'ck' (as when array = 'ck' len(arraw[1:]) == 1) but how do we ever get 'ick' as an array in the recursion? Could you visualize this anyhow? Thanks a lot for any tips!

Valentin Lorentz
  • 9,556
  • 6
  • 47
  • 69
Dora
  • 1,163
  • 2
  • 9
  • 11
  • If `array` starts out as `'mick'`, then the 1st recursive call gets passed `array[1:]`, which is `'ick'`. It might help if you try & work through the algorithm manually, on paper. Another thing that might help is to pass an extra `depth` argument to `permut`, i.e., define it with `def permut(array, depth=0):` and call it recursively with `for permutation in permut(array[1:], depth+1):` and change your print statement to `print depth, permutation, array`. – PM 2Ring Jan 02 '16 at 14:26
  • BTW, `array` isn't a great variable name, especially for a string. People will assume it's supposed to be a `list`, or a [Numpy](http://docs.scipy.org/doc/numpy-1.10.0/reference) array, or a standard library [`array`](https://docs.python.org/2/library/array.html). – PM 2Ring Jan 02 '16 at 14:29
  • You called `permut()` with `array[1:]` and `'mick'[1:] == 'ick'`.your output is correct. – Kenly Jan 02 '16 at 14:52

1 Answers1

1
permut('Mick')                 # recursion: for permutation in permut('ick')
    permut('ick')              # recursion: for permutation in permut('ck')
        permut('ck')           # recursion: for permutation in permut('k')
            permut('k')        # return ['k']
        permut('ck')           # continue from the loop
                               # print each element of ['k'] with 'ck'
                               # return res, which is ['ck', 'kc']
    permut('ick')              # continue from the loop
                               # print each of ['ck', 'kc'] with 'ick'
                               # return res, which is ['ick', 'cik', 'cki', 'ikc', 'kic', 'kci']
permut('Mick')                 # continue from loop
                               # print each of the above elements + 'Mick' individually
                               # return res, which is... long

The above basically permutes all letters in the word, which can be simply achieved with

>>> import itertools as it
>>> res = list(''.join(p) for p in it.permutations('Mick'))
>>> print res
['Mick', 'Mikc', 'Mcik', 'Mcki', 'Mkic', 'Mkci', 'iMck', 'iMkc', 'icMk', 'ickM', 'ikMc', 'ikcM', 'cMik', 'cMki', 'ciMk', 'cikM', 'ckMi', 'ckiM', 'kMic', 'kMci', 'kiMc', 'kicM', 'kcMi', 'kciM']
Reti43
  • 9,656
  • 3
  • 28
  • 44
  • Thanks @Reti43. I sort of get that this is going on, but when I print the permutation and array right after the for loop, I'm expecting 'k' for both values as that's the return value of permut(array[1:]). So what's going on that the first printed value skips to 'ck'? Another thing: why does it continue to loop back to 'ick' and 'Mick' when the permut recursion goes the other direction? – Dora Jan 02 '16 at 15:54
  • @DóraJámbor You have 4 different stacks of the function `permut()`, with different inputs. Each of them do their own thing. `print permutation` just prints each element of whatever `permut(array[1:])` returns. When you're in `permut('ick')`, the result of `for permutation in permut('ck')` becomes `for permutation in ['ck', 'kc']`, so that's what is printed. When you call `permut(array[1:])`, you don't change what `array` is for the current stack. I don't know whether that makes sense to you. I'm not entirely sure what you're confused with. – Reti43 Jan 02 '16 at 16:06
  • @DóraJámbor But to be clear, the first time you print `ck` is when you're in the `permut('ick')` stack. The reason why the function continues all the way back to 'Mick' is because that was the initial function. When you're in `permut('Mick'), you have to temporarily stop what you're doing until you get back the result of `permut('ick'). Then you continue with what you were doing with `permut('Mick'). Think of it like opening and closing brackets in a formula. For example, (a + (b * c + (d - e)) + f). – Reti43 Jan 02 '16 at 16:13
  • Actually the main point I didn't get here was the way 'permutation' in permut[1:] was updated by whatever the res list contained. That is, I did not realize that after each for loop finished up the permut[1:] would be the returned res value, through which permutation could loop through. Anyways, thanks for the explanations! – Dora Jan 04 '16 at 10:21