4

I have a list containing n integers. The ith element of the list a, a[i], can be swapped into any integer x such that 0 ≤ x ≤ a[i]. For example if a[i] is 3, it can take values 0, 1, 2, 3.

The task is to find all permutations of such list. For example, if the list is

my_list = [2,1,4]

then the possible permutations are:

[0,0,0], [0,0,1], ... [0,0,4],
[0,1,0], [0,1,1], ... [0,1,4],
[1,0,0], [1,0,1], ... [1,0,4],
[1,1,0], [1,1,1], ... [1,1,4],
[2,0,0], [2,0,1], ... [2,0,4],
[2,1,0], [2,1,1], ... [2,1,4]

How to find all such permutations?

FObersteiner
  • 22,500
  • 8
  • 42
  • 72
  • 3
    Your wording is not clear here. In your example, would `[2,2,4]` be a valid permutation (having replaced the second element with 2)? Your second sentence indicates yes but I predict that is not an exactly true statement. What you have said is you can replace the 1st element with 0 or 1, the 2nd with 0,1 or 2, the third by 0,1,2 or 3. I imagine you want each element to be able to be replaced with an integer lower than its VALUE (not index), but that is not what your question says. – Hoog Jul 24 '19 at 12:43
  • 2
    @Hoog Yes you got it right, that is what I want. I've updated the question accordingly. –  Jul 24 '19 at 12:55

3 Answers3

3

you could use a comibation of range to get all the 'valid' values for each element of the list and itertools.product:

import itertools

my_list = [2,1,4]

# get a list of lists with all the possible values
plist = [list(range(y+1)) for y in my_list]

#
permutations = sorted(list(itertools.product(*plist)))

more on itertools product see e.g. here on SO or the docs.

FObersteiner
  • 22,500
  • 8
  • 42
  • 72
0

Try this. Let me know if I misunderstood your question

def permute(l,cnt,n):
    if cnt==n:
        print(l)
        return 
    limit = l[cnt]
    for i in range(limit+1):
        l[cnt]=i
        permute(l[:n],cnt+1,n)
    
l =[2,1,4]
permute(l,0,3)
FObersteiner
  • 22,500
  • 8
  • 42
  • 72
Parijat Bhatt
  • 664
  • 4
  • 6
  • 1
    nice recursive solution! although it takes some more iterations than there are premutations. some comments on how this works and how to use it would be nice. – FObersteiner Jul 30 '19 at 11:41
  • 1
    This is a kind of brute force solution. We know that finally, we will have an array of size n and at each index the value can be varied in a range say x to y where x is 1 and y is the_given_array[index] so you can view the recursion call to be doing something like putting 0 at 0 then 0 at 1.... printing 00000 followed by 00001... I hope this helps. Let me know if you need more explanation and ideally it should take iterations only the required number of times. – Parijat Bhatt Jul 31 '19 at 19:52
0

Here's a solution:

my_list=[2,1,4]    
def premutation_list(p_list):
    the_number=int("".join(map(str,p_list)))
    total_len=len(str(the_number))
    a=[i for i in range(the_number)]
    r_list=[]
    for i in a:
        if len(str(i))<total_len:
            add_rate=total_len - len(str(i))
            b="0,"*add_rate
            b=b.split(",")
            b=b[0:len(b)-1]
            b.append(str(i))
            r_list.append([int(y) for x in b for y in x ])
        else:
            r_list.append([int(x) for x in str(i)])

    return r_list
print(premutation_list(my_list))

Explanation:

  • The basic idea is just getting all the numbers till the given number. For example till 4 there are 0,1,2,3, number.
  • I have achieved this first by converting the list into a integer.
  • Then getting all the numbers till the_number.
Faraaz Kurawle
  • 1,085
  • 6
  • 24