Smallest permutation of a given number

I have a number as a string and I want to find the smallest number consisting of the digits of the original number, i.e.

56340902138765401345 -> 10001233344455566789

      

I am converting a string to a list and sorting it.

num = '56340902138765401345'
a = list(num)
a.sort()

      

Since the number cannot start from zero (but I need to use zeros from the original number), I search for the first non-zero element and put it in front:

inext = next(i for i, x in enumerate(a) if x != '0')
a.insert(0, a.pop(inext))

      

Then I convert the list back to a string and display it.

num2 = ''.join(map(str, a))
print(num2)

      

It works, but it doesn't seem very pythonic or elegant to me. Is there a better way?

+3


source to share


3 answers


We can count zeros. Then we remove the zeros from the number, sort and collect it. For assembly, we use the first digit, then we add our zeros and then the rest of our sorted numbers.

num = '56340902138765401345'

nzeros = num.count('0')
num = ''.join(sorted(num.replace('0', '')))
print num[0] + ('0' * nzeros) + num[1:]

      



Result:

 10001233344455566789

      

+4


source


There are a few minor things that could be improved.

a = list(num)
a.sort()

      

can be replaced with

a = sorted(num)

      



The string can be restored from the list with ''.join(sorted(num)

.

Putting this together, you can use a regular expression to traverse leading zeros past the first non-zero digit:

import re
a = re.sub(r'^(0+)(.)', r'\2\1', ''.join(sorted(num)))

      

I wouldn't argue that this is more Pythonic, but it is rather concise and possibly more elegant (depending on who looks like).

+3


source


What about

num = "".join(sorted(num))
nonzero = num.rfind("0") + 1
if nonzero:
    num[0] = num[nonzero]
    num[nonzero] = "0"

      

If num is not "0"

, then it rfind

returns -1

, so it nonzero

evaluates to False

.

0


source







All Articles