Create a function that takes a positive integer and returns the next bigger number that can be formed by rearranging its digits. For example:

```
12 ==> 21
513 ==> 531
2017 ==> 2071
```

If the digits can't be rearranged to form a bigger number, return `-1` (or `nil` in Swift):

```
9 ==> -1
111 ==> -1
531 ==> -1
```

Difficulty: interview

Starter code:

def next_bigger(n):
	

Solutions:
import itertools
def next_bigger(n):
    s = list(str(n))
    for i in range(len(s)-2,-1,-1):
        if s[i] < s[i+1]:
            t = s[i:]
            m = min([x for x in t if x>t[0]])
            t.remove(m)
            t.sort()
            s[i:] = [m] + t
            return int("".join(s))
    return -1


def next_bigger(n):
    # algorithm: go backwards through the digits
    # when we find one that's lower than any of those behind it,
    # replace it with the lowest digit behind that's still higher than it
    # sort the remaining ones ascending and add them to the end
    digits = list(str(n))
    for pos, d in reversed(tuple(enumerate(digits))):
        right_side = digits[pos:]
        if d < max(right_side):
            # find lowest digit to the right that's still higher than d
            first_d, first_pos = min((v, p) for p, v in enumerate(right_side) if v > d)

            del right_side[first_pos]
            digits[pos:] = [first_d] + sorted(right_side)

            return int(''.join(digits))

    return -1


def next_bigger(n):
    n = str(n)[::-1]
    try:
        i = min(i+1 for i in range(len(n[:-1])) if n[i] > n[i+1])
        j = n[:i].index(min([a for a in n[:i] if a > n[i]]))
        return int(n[i+1::][::-1]+n[j]+''.join(sorted(n[j+1:i+1]+n[:j]))) 
    except:
        return -1


def next_bigger(n):
    nums = list(str(n))
    for i in reversed(range(len(nums[:-1]))):
        for j in reversed(range(i, len(nums))):
            if nums[i] < nums[j]:
                nums[i], nums[j] = nums[j], nums[i]
                nums[i + 1:] = sorted(nums[i + 1:])
                return int(''.join(nums))
    return -1

def next_bigger(n):
    i, ss = n, sorted(str(n))

    if str(n) == ''.join(sorted(str(n))[::-1]):
        return -1;

    while True:
        i += 1;
        if sorted(str(i)) == ss and i != n:
            return i;


def next_bigger(n):
    prefix = list(str(n))
    postfix = [prefix.pop()]

    while prefix and prefix[-1] >= max(postfix):
        postfix.append(prefix.pop())

    if not prefix:
        return -1

    postfix.sort()
    i = next(i for i, d in enumerate(postfix) if d > prefix[-1])
    postfix[i], prefix[-1] = prefix[-1], postfix[i]
    return int(''.join(prefix + postfix))

def next_bigger(n):
    if str(n) == ''.join(sorted(str(n))[::-1]):
        return -1
    a = n
    while True:
        a += 1
        if sorted(str(a)) == sorted(str(n)):
            return a

def next_bigger(n):
    nums = list(str(n))
    length = len(nums) - 1
    suffix = length
    while nums[suffix - 1] >= nums[suffix] and suffix > 0:
        suffix -= 1
    if suffix <= 0:
        return -1

    rightmost = length
    while nums[rightmost] <= nums[suffix - 1]:
        rightmost -= 1
    nums[suffix - 1], nums[rightmost] = nums[rightmost], nums[suffix - 1]

    nums[suffix:] = nums[length:suffix - 1:-1]
    return int(''.join(nums))


def next_bigger(n):
    m = [d for d in str(n)]
    for d in range(len(m)-1, 0, -1):
        if max(m[d:]) > m[d-1]:
            i = min((x for x in range(d, len(m)) if m[x] > m[d-1]), key = lambda k : m[k])
            m[d-1], m[i] = m[i], m[d-1]
            m[d:] = sorted(m[d:])
            break
    else:
        return -1
    return int("".join(m))