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
```

Source: codewars | Difficulty: MEDIUM_HARD
Tags: String algorithms

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):
	digits = list(str(n))
	for (pos, d) in reversed(tuple(enumerate(digits))):
		right_side = digits[pos:]
		if d < max(right_side):
			(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))