I am working on a program that requires me to read in and validate a number, but in doing so I need to take a two digit integer (for example we'll say 18) and add it 1 + 8. Now I have it working where I do a conditional check if it is greater than 10 and subtract, but that's kind of an ugly solution in my opinion and was wondering if there is a cleaner way of doing it?
-
1Are you saying that you want to read in a string representation of a number and compute the sum of the last two digits of that number? If so, is it guaranteed that the number has at least two digits? – Cary Swoveland Nov 26 '14 at 05:47
6 Answers
You can use the modulo operator n % 10
, to get the rightmost digit. For example:
18 % 10
# => 8
9 % 10
# => 9
0 % 10
# => 0
(-123).abs % 10
# => 3
To handle negative numbers, use Integer#abs.
EDIT
Ruby 2.4 has a Integer#digits method. It will give you the digits as an array, starting from unit's place. And if you want to add the digits, you can use Enumerable#sum.
123.digits
# =>[3, 2, 1]
123.digits.first
# => 3
123.digits.sum
# => 6

- 28,097
- 9
- 82
- 87
To add all digits from a number, you can use the following:
18.to_s.chars.map(&:to_i).reduce(:+)
It transforms the number into a string, splits it into digits, transforms each into an integer and adds them all together.
Works with numbers of any length.

- 38,386
- 18
- 74
- 98
This is how I would do it:
any_number = 1234
# Ensure your input is at most a two digit number (might not be needed)
two_digit_number = any_number % 100 #=> 34
# Calculate the final addition
total = two_digit_number / 10 + two_digit_number % 10 #=> 7

- 1,046
- 7
- 10
For two digit integers, there is at least another method we could use: Numeric#divmod
, which returns the quotient and modulus in an array. And here's a look at the speed of the different approaches to sum up the digits:
b = 18
n = 1_000_000
Benchmark.bmbm do |x|
x.report('to_s:') { n.times { b.to_s.chars.map(&:to_i).reduce(:+) }}
x.report('divmod:') { n.times { b.divmod(10).reduce(:+) }}
x.report('direct division:') { n.times { b/10 + b%10 } }
x.report('digits:') { n.times { a.digits.reduce(:+) } }
end
#####
user system total real
to_s: 0.750000 0.000000 0.750000 ( 0.750700)
divmod: 0.150000 0.000000 0.150000 ( 0.153516)
direct division: 0.080000 0.000000 0.080000 ( 0.076697)
digits: 0.560000 0.020000 0.580000 ( 0.574687)

- 3,210
- 2
- 14
- 22
-
I ran this benchmark with `ruby-2.6.0` and I get very different results, at least for the `digits` method. Also why the variable used in digits method is `a` instead of `b` thats used with every other method? – Santhosh Feb 20 '20 at 14:06
Here a hands on solution for the fun of it:
def get_digits(n)
res=[]; i=0;
while 10**i < n
res.push( n/10**i%10 )
i += 1
end
return res
end

- 771
- 11
- 20
def digits_sum(number,n)
number_array=number.to_s.chars
n=[n,number_array.length].min
number_array.slice(-n,n).map {|c| c.to_i }.reduce(:+) || 0
end
this method return the sum of N right-digits.
digits_sum 123456789,5 => 35
digits_sum 123456789,2 => 17
This will work if you give N greater then number length but wont work if negative count is provided

- 2,404
- 13
- 23