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?
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
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.
.chars
instead of .split('')
–
Clementius This will do:
int = 10000023
int.digits.first(2).sum
# => 5
int.digits
: This method returns an array of digits of the integer int
, starting from the least significant digit to the most significant one.
first(n)
: This method is chained to digits and retrieves the first n
elements from the array of digits, which are the last two digits of the integer.
sum
: This method calculates the sum of all elements in the array returned by digits.first(2)
. In this case, it calculates the sum of the first two digits of the integer.
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
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)
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? –
Stinson 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
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
© 2022 - 2024 — McMap. All rights reserved.