有一个函数d(n)被定义为n的适当除数之和(小于n的数字均匀分成n)。例如,220的适当除数是1,2,4,5,10,11,20,22,44,55和110;因此d(220)= 284. 284的适当除数是1,2,4,71和142;所以d(284)= 220。
我想在Ruby中实现这个d(n)函数。我的第一直觉是使用for循环遍历所有值到n并检查模数。以下代码有效:
我可以使用这样的for循环来实现它:
def d(n)
proper_divisors = []
for i in 1...n
if (n % i == 0)
proper_divisors.push(i)
end
end
return proper_divisors.inject(:+)
end
但是从之前的回答中我了解到it's very rare to use a for loop in Ruby
。这就是我尝试这个的原因:
def d(n)
(1..n).inject(0) { |total| total+ n if (n % (1..n) == 0) }
end
因此,根据1 to n
的值,我从total
开始等于0并将n
添加到total
,如果n
可以平均分为数字从1到n。自if (n % (1..n) == 0)
以来,Range can't be coerced into Fixnum (TypeError)
部分无效。
如何实现我对一个范围取一个数的模数,如果它等于零则返回true?
答案 0 :(得分:4)
(toro2k的答案的固定版本)
def d(n)
(1..n/2).inject(0) { |total, m| (n % m).zero? ? total + m : total }
end
d(220) # => 284
阻止inject
接受两个参数:集合的累加器和当前元素。该块应该返回累加器的新值。在您的代码中,您忽略当前元素(这会让您尝试将n
除以范围)
答案 1 :(得分:2)
我做了以下事情: -
def d(n)
(1..(n/2)).each_with_object(total = 0){|ele| total += ele if n%ele == 0 }
total
end
答案 2 :(得分:2)
效率不如Sergio Tulentsev的答案,但更简单:
def d n
(1..n / 2).select{|m| (n % m).zero?}.inject(:+)
end