这是更好的方法吗?

时间:2016-08-23 06:18:41

标签: ruby

我写了一个简单的脚本来对正整数输入的所有数字求和,直到剩下1位数(例如输入12345结果是6,因为1 + 2 + 3 + 4 + 5 = 15和1 + 5 = 6)。它有效,但它是更好的方法吗? (更正确?)

这是一个代码:

def sum(n)
  string=n.to_s
  while string.length > 1 do
    result=string.chars.inject { |sum,n| sum = sum.to_i + n.to_i}
    string=result.to_s
  end
  puts "Sum of digits is " + string 
end

begin
  p "please enter a positive integer number:"
  number = Integer(gets.chomp)
  while number<0
    p "Number must be positive!Enter again:"
    number = Integer(gets.chomp)
  end 
rescue
  p "You didnt enter integer!:"
  retry
end

sum(number)

5 个答案:

答案 0 :(得分:4)

根据维基百科,formula是:

  

dr( n )= 1 +(( n - 1)mod 9)

所以归结为:

def sum(n)
  1 + (n - 1) % 9
end

要考虑0,您可以添加return 0 if n.zero?

答案 1 :(得分:2)

您可以使用divmod(商和模数)来计算数字和,而无需转换为/来自字符串。这样的事情应该有效:

def sum(number)
  result = 0
  while number > 0 do
    number, digit = number.divmod(10)
    result += digit
    if number == 0 && result >= 10
      number = result
      result = 0
    end
  end
  result
end

sum(12345) #=> 6

该行

number, digit = number.divmod(10)

基本上剥掉了最后一位数字:

12345.divmod(10) #=> [1234, 5]

1234成为新的number5被添加到result。如果number最终变为零且result等于或大于10(即多于一位数),result将成为新number(例如{{} 1}})并且循环重新开始。如果15低于result(即一位数),则退出循环并返回10

答案 2 :(得分:1)

这对我来说很好看。你可以做一些更简单的事情,例如使用map将每个字符变成一个整数。

def sum(n)
  string=n.to_s
  while string.length > 1 do
    result = string.chars.map(&:to_i).inject(&:+)
    string = result.to_s
  end
  puts "Sum of digits is " + string 
end

答案 3 :(得分:1)

简短的递归版本:

def sum_of_digits(digits)
  sum = digits.chars.map(&:to_i).reduce(&:+).to_s
  sum.size > 1 ? sum_of_digits(sum) : sum
end

p sum_of_digits('12345') #=> "6"

单一呼叫版本:

def sum_of_digits(digits)
  digits = digits.chars.map(&:to_i).reduce(&:+).to_s until digits.size == 1
  return digits
end

答案 4 :(得分:0)

您还可以使用.digits,因此不必将输入转换为字符串。

def digital_root(n)

  while n.digits.count > 1 
    array = n.digits 
    n = array.sum
  end
  return n

end