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