'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) in Ruby
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!
Solution 1:[1]
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 }
Solution 2:[2]
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
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Cary Swoveland |
