Home > OS >  Find the smallest 4-digit number that decreases by 27 when you move its last digit to the first posi
Find the smallest 4-digit number that decreases by 27 when you move its last digit to the first posi

Time:05-18

I'm trying to run standard ruby training programs, but I had a problem with this program, please take a look. Thank you very much! Code:

q = 9999 #last 4-digit number

while q > 1000                  #from 9999 to 1000, for exemple, the cycle has arrived to 6784

    d = q.to_s.chars.map(&:to_i)        #transform 6784 to array [6, 7, 8, 4]

    p = d                   # create sample array with [6, 7, 8, 4]

    tmp = p[0];                 # tmp = 6;

    p[0] = p[3];                # 6 = 4;

    p[3] = tmp;                 # 4 = 6

    g = p.join.to_i             # transform [4, 7, 8, 6] to 4786

    f = q - g               # 6784 - 4786

    if f == 27              # i need to find the smallest 4-digit number that decreases by 27 when moving its last digit to the first position

        puts q              #print 4-digit number that decreases by 27 when moving its last digit to the first position

    end

    q = q - 1; 

end

But the result does not appear, it is because it is not, or somewhere a mistake.

In general, the condition of the task is: Find the smallest 4-digit number that decreases by 27 when you move its last digit to the first position. (Use the find or detect method). Thank You!

CodePudding user response:

I would define a method to "rotate" the number using string manipulation.

def rotate_number_one_digit(n)
  s = n.to_s
  "#{s[-1]}#{s[0..-2]}".to_i
end

Then I would use #upto to deal with the iteration.

1000.upto(9999) do |x|

end

Each time around you'll check that the "rotated" number plus 27 equals x. If so, print it and break the loop to prevent further unnecessary iteration.

1000.upto(9999) do |x|
  if rotate_number_one_digit(x)   27 == x then
    puts x
    break
  end
end

Or we can just use the #find method from Enumerable.

1000.upto(9999).find { |x| rotate_number_one_digit(x)   27 == x }

CodePudding user response:

I will first create a helper method to convert an array of digits to an integer.

def digits_to_int(arr)
  arr.reduce { |n,d| n*10   d }
end

For example,

digits_to_int [1,2,3,4]
  #=> 1234

This tends to be faster than arr.join.to_i (see sawa's answer here).

We can then simply compute

(1..).find { |n| n-27 == digits_to_int(n.digits.rotate.reverse) }
  #=> 30

See Enumerable#reduce (a.k.a. inject), "Endless range", Integer#digits, Array#rotate and Array#reverse.


Here is an example calculation.

n = 243
a = n.digits
  #=> [3,4,2]
b = a.rotate
  #=> [4,2,3]
c = b.reverse
  #=> [3,2,4]
d = digits_to_int(c)
  #=> 324
n - 27 == d
  #=> 243 - 27 == 324 => false

and another

n = 30
a = n.digits
  #=> [0,3]
b = a.rotate
  #=> [3,0]
c = b.reverse
  #=> [0,3]
d = digits_to_int(c)
  #=> 3
n - 27 == d
  #=> 30 - 27 == 3 => true
  •  Tags:  
  • ruby
  • Related