Problem Statement

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, None in Rust):

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

My attempts failed, although I was making progress gradually. At first, I tried using itertools.permutations() to create a list of all permutations of the digits of the given number. I iterated through the list and removed all elements less than the given integer itself, sorted it using sorted() and returned the 2nd element of the final list. Sure enough, I passed the test cases and I was jubilant

However, I failed the more advanced test cases because my code took so long to execute with some gargantuan numbers that the execution timed out in Codewars’ console. It looks like brute-forcing the problem didn’t work. Then, I realized I could take a far simpler approach to this problem by imagining how I’d solve this problem with my mind on paper and not how a computer would solve it

I found that I could simply swap the last two digits and get the answer, which worked for a few test cases but failed for some others. I am posting the actual solution, which I found online and tried to understand after wasting a lot of time figuring out a solution for myself (I have added comments to the code to explain it)

def next_bigger(n):
	# Convert int to string for processing
	s = str(n)
 
	# looping through string, going in reverse
	for i in range(len(s)-2, -1, -1):
		# if left digit is smaller than right digit in the pair
		if s[i] < s[i+1]:
			# starting from end till where we stopped
			for k in range(len(s)-1, i, -1):
				# find next bigger digit 
				if s[i] < s[k]:
					# swap those digits, sort the numbers to its right
					return int(s[:i] + s[k] + s[-1:k:1] + s[k] + s[k-1:i:-1])
 
	# if all else failed
	return -1

My learnings

  • Think in simple terms. Approach a problem like how you would do it on paper and take it from there
  • I need to be faster with the tools of the trade
  • I am losing my mental stamina and patience when I feel like I’m on the cusp of giving up. Seeing huge snippets of code and long text of explanations, I fail to understand and follow through
  • Code-speciific mistakes
    • Python does not support assignment operations in strings. I mistakenly tried s[-2] = s[-1], which won’t work. Strings are immutable by nature. To work around this, convert strings to lists using list()