Write a function that takes a positive integer and returns the next smaller positive integer containing the same digits.

For example:

```python
next_smaller(21) == 12
next_smaller(531) == 513
next_smaller(2071) == 2017
```

Return -1 (for `Haskell`: return `Nothing`, for `Rust`: return `None`), when there is no smaller number that contains the same digits. Also return -1 when the next smaller number with the same digits would require the leading digit to be zero.

```python 
next_smaller(9) == -1
next_smaller(135) == -1
next_smaller(1027) == -1  # 0721 is out since we don't write numbers with leading zeros
```
```ruby 
next_smaller(9) == -1
next_smaller(135) == -1
next_smaller(1027) == -1  # 0721 is out since we don't write numbers with leading zeros
```

 * some tests will include very large numbers.
 * test data only employs positive integers.

*The function you write for this challenge is the inverse of this kata: "[Next bigger number with the same digits](http://www.codewars.com/kata/next-bigger-number-with-the-same-digits)."*

Difficulty: interview

Starter code:

def next_smaller(n):
	

Solutions:
def next_smaller(n):
    s = list(str(n))
    i = j = len(s) - 1
    while i > 0 and s[i - 1] <= s[i]: i -= 1
    if i <= 0: return -1
    while s[j] >= s[i - 1]: j -= 1
    s[i - 1], s[j] = s[j], s[i - 1]
    s[i:] = reversed(s[i:])
    if s[0] == '0': return -1
    return int(''.join(s))

def next_smaller(n):
    
    ## Create a list of each digit in n
    numbers = [int(i) for i in str(n)]

    ## Loop over each digit in the numbers list, from right to left
    for i in range(len(numbers) - 1, 0, -1):
    
        ## If a number is less than the number to its left, split into 2 lists
        if numbers[i] < numbers[i -1]:
            rearrange_list = numbers[i - 1:]  ## numbers on the right of i -1
            original_list = numbers[:i - 1]   ## numbers on the left of i -1
            less_than_values = []             ## will contain possible substitutions for i -1
            
            ## Loop over the rearrange_list
            for i in rearrange_list:
            
                ## if the number is smaller than i, append it to less_than_values
                if i < rearrange_list[0]:
                    less_than_values.append(i)
    
            ## Add the max value from less_than_values to the end of the original_list, 
            ## then add the rest of the sorted values from rearrange_list to the original_list
            original_list.append(max(less_than_values))
            rearrange_list.remove(max(less_than_values))
            original_list += sorted(rearrange_list, reverse=True)
            
            ## Join the list together to get the output
            output = int(''.join([str(num) for num in original_list]))

            ## If the output starts with 0, return -1. Otherwise, return the ouput.
            if len(str(output)) < len(str(n)):
                return -1
            else:
                return output
    
    ## Return -1 if n is None, or if there are no smaller numbers
    return -1            


def swap(s, a, b):
    s = list(s)
    s[a], s[b] = s[b], s[a]
    return ''.join(s)
    
def maximized_range(s, left): # Maximize value in range [left, end]
    return s[:left] + ''.join(sorted(s[left:], reverse=True))

def next_smaller(n):
    s = str(n)
    k = len(s)
    for i in range(k-1, -1, -1):
        for j in range(k-1, i, -1):
            if s[j] < s[i]:
                t = swap(s, i, j)
                if t[0] != '0':
                    return int(maximized_range(t, i+1))
    return -1

from operator import itemgetter

def next_smaller(n):
    s        = str(n)
    LR_Pairs = list(enumerate(zip(s,s[1:])))                                                    # Association pair (l,r) and index of left char of the pair
    iP,pivot = next( ((i,l) for i,(l,r) in reversed(LR_Pairs) if l>r), (-1,-1) )                # Extract first increasing pair, coming from the end,...
                                                                                                # ... then get the left char (pivot) and it's index
    if iP == -1: return -1                                                                      # No smaller number...
    
    iM,mx = max( ((i,c) for i,c in enumerate(s[iP+1:],iP+1) if c < pivot), key=itemgetter(1))   # Highest char smaller than 'pivot' and its index
    nextS = s[:iP] + mx + ''.join(sorted(s[iP:iM]+s[iM+1:], reverse=True))                      # Move 'mx' in place of 'pivot', then sort all the remaining chars, descending
    
    return int(nextS) if nextS[0] != '0' else -1

#先确定要改变的范围，然后在对指定范围进行改动
#itertools是很好用的包，注意学习
import itertools
def next_smaller(n):
    print(n)
    a=list(str(n))
    b=len(a)
    if b==1:
        return -1
    for j in range(b-2,-1,-1):
        if a[j] > a[j+1]:         
            t=a[j:]
            m=max([x for x in t if x<t[0]])
            t.remove(m)
            c=[]
            while len(t)>0:
                d=max(t)
                c.append(d)
                t.remove(d)
            a[j:]=[m]+c
            if a[0]=='0':
                return -1
            return int(''.join(a))
    return -1


def next_smaller(n):
    nums = list(map(int, list(str(n))))
    seen = []
    for i in reversed(range(1, len(nums))):
        if nums[i - 1] > nums[i]:
            seen.append(nums[i])
            seen.append(nums[i-1])
            seen = sorted(seen, reverse=True)
            for j in range(len(seen)):
                if seen[j] < nums[i-1]:
                    winner = seen.pop(j)
                    break
            if winner == 0 and i == 1:
                return -1

            nums = nums[:i-1]
            nums.append(winner)
            nums.extend(seen)
            return int(''.join(map(str, nums)))
        else:
            seen.append(nums[i])

    return -1

def f(s):
    if ''.join(sorted(s)) == s:
        return ''
    ss = s[1:]
    if ''.join(sorted(ss)) == ss:
        xs = sorted(s, reverse=True)
        next_1st_digit = max(x for x in set(xs) if x < s[0])
        xs.remove(next_1st_digit)
        return next_1st_digit + ''.join(sorted(xs, reverse=True))
    return s[0] + str(f(ss))
    
def next_smaller(n):
    s = f(str(n))
    return int(s) if s and not s.startswith('0') else -1

def next_smaller(n):
    s = str(n)
    i = next((i for i in range(len(s)-1,0,-1) if s[i-1]>s[i]),len(s))
    j = next((j for j in range(len(s)-1,i-1,-1) if s[i-1]>s[j]),-1)
    s = s[:i-1]+s[j]+(s[i:j]+s[i-1]+s[j+1:])[::-1]
    return [int(s),-1][s[0]=='0' or j<0]


def next_smaller(n):
    num = list(str(n))

    try:
        pivot = next(i for i in reversed(range(len(num) - 1)) if num[i] > num[i + 1])
    except StopIteration:
        return -1
    swap  = next(i for i in reversed(range(len(num))) if num[pivot] > num[i])

    num[pivot], num[swap] = num[swap], num[pivot]
    num[pivot + 1:] = reversed(num[pivot + 1:])

    if num[0] == '0':
        return -1

    return int(''.join(num))

def next_smaller(n):
    list_number = list(map(lambda x: int(x), str(n)))

    center = None

    for i in range(len(list_number) - 1, 0, -1):
        if list_number[i] < list_number[i-1]:
            center = list_number[i-1]
            left = list_number[:i-1]
            right = list_number[i:len(list_number)]
            break

    if center is None:
        return -1
    else:
        right.sort(reverse=True)
        for i in right:
            if i < center:
                right.append(center)
                center = i
                right.remove(i)
                right.sort(reverse=True)
                left.append(center)
                left.extend(right)
                if left[0] == 0:
                    return -1
                return int(''.join(str(n) for n in left))