HiveBrain v1.2.0
Get Started
← Back to all entries
patternrubyMinor

Function that takes a positive integer number and returns the next bigger number formed by the same digits

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
samenumberthebiggerdigitsfunctionnextthatreturnsand

Problem

I am taking on this challenge on CodeWars. You have to create a function that takes a positive integer number and returns the next bigger number formed by the same digits:

next_bigger(12)==21
next_bigger(513)==531
next_bigger(2017)==2071


This is my solution:

def next_bigger(s)
      s.to_s.split("").permutation.to_a.map {|a| a.join("").to_i }.reject { |n| n <= s }.inject do |memo, p| 
      (memo-s) < (p-s) ? memo : p
  end
 end


That passes these tests:

Test.assert_equals(next_bigger(12),21)
Test.assert_equals(next_bigger(513),531)
Test.assert_equals(next_bigger(2017),2071)
Test.assert_equals(next_bigger(414),441)
Test.assert_equals(next_bigger(144),414)


But I am being told my code is too inefficient. I am doing a few of these challenges each day to improve my ruby (I am a beginner). Could someone recommend how this could be made more efficient?

Solution

The question of finding the next permutation in lexicographic order is a classical one (going back 7 centuries) and well documented in the literature. E.g. Wikipedia gives the following algorithm:



  • Find the largest index k such that a[k]



  • Find the largest index l greater than k such that a[k]



  • Swap the value of a[k] with that of a[l].



  • Reverse the sequence from a[k + 1] up to and including the final element a[n].

Context

StackExchange Code Review Q#143791, answer score: 5

Revisions (0)

No revisions yet.