Search code examples
pythonnumberslogic

Generate numbers with strictly decreasing digits


I am trying to generate numbers of maximum length n whose all digits are strictly decreasing.

If ‍‍n = 5‍, then numbers would be :

54321
5432
543
54
5421
542
541
5321
532
53
521
52
51
5
4321
432
43
431
421
42
41
4
...

Any hints on how to proceed?

Thank you in advance

Edit - My current code looks like this and I am not getting all the results.

def func(arr):
for x in arr:
    token=x[-1]
    k=int(token)-1
    while k>1:
        for i in range(1,k):
            f.write(x)
            for j in range(k,i,-1):
                f.write(str(j))
        k-=1

f = open ("demo.txt", "w")

arr = ["987"]
for i in range(986,321,-1):
    tens = i
    units = i%10
    tens = int(tens)/10
    hundreds = int(tens)/10 
    tens%=10
    hundreds%=10
    if tens >= hundreds or units>= tens:
        continue
    arr.append(str(i))

func(arr)
f.close()

Solution

  • Here is a recursive generator function:

    def nums(n):
        if n:
            yield from (int(f"{n}{num}") for num in nums(n-1))
            yield n
            yield from nums(n-1)
           
    
    [*nums(1)]
    # [1]
    [*nums(2)]
    # [21, 2, 1]
    [*nums(3)]
    # [321, 32, 31, 3, 21, 2, 1]
    [*nums(4)]
    # [4321, 432, 431, 43, 421, 42, 41, 4, 321, 32, 31, 3, 21, 2, 1]
    

    Or using the itertools.combinations approach:

    from itertools import combinations
    
    def nums(n):
        for l in range(n, 0, -1):
            for c in combinations(range(n, 0, -1), l):
                yield int("".join(map(str, c)))
    
    [*nums(2)]
    # [21, 2, 1]
    [*nums(3)]
    # [321, 32, 31, 21, 3, 2, 1]
    [*nums(4)]
    # [4321, 432, 431, 421, 321, 43, 42, 41, 32, 31, 21, 4, 3, 2, 1]