我试图在Ruby中解决Project Euler Question#21。
设d(n)定义为n的适当除数之和(小于n的数均匀分为n)。 如果d(a)= b并且d(b)= a,其中a≠b,则a和b是友好对,并且a和b中的每一个被称为友好数字。 例如,220的适当除数是1,2,4,5,10,11,20,22,44,55和110;因此d(220)= 284. 284的适当除数是1,2,4,71和142;所以d(284)= 220。 评估10000以下所有友好数字的总和。
我使用暴力方法找到一个解决方案,找到[2,10000]范围内每个数的所有除数之和,并将它们推入一个哈希对象。
require 'prime'
#Method reference http://stackoverflow.com/questions/3398159/all-factors-of-a-given-number
def factors_of(number)
primes, powers = number.prime_division.transpose
exponents = powers.map{|i| (0..i).to_a}
divisors = exponents.shift.product(*exponents).map do |powers|
primes.zip(powers).map{|prime, power| prime ** power}.inject(:*)
end
#Modified line
divisors.sort![0..divisors.size-2]
end
ht=Hash.new
(2..10000).each do |x|
arr=factors_of(x)
sum=arr.reduce(:+)
ht[x]=sum
end
amicable=ht.select { |key, value| value==ht.key(key) && ht.key(key)!=key}
puts amicable
此代码的输出
{220=>284, 284=>220, 1184=>1210, 1210=>1184, 2620=>2924, 5020=>5564, 5564=>5020, 6232=>6368, 6368=>6232}
它找到除{2924 => 2620}以外的所有友好对。除了{2620 => 2924},{2924 => 2620}之外,所有其他数字都具有其反向对。我在这里缺少什么?有什么想法吗?谢谢。
答案 0 :(得分:0)
知道了!
Hash#key
返回具有参数值的第一个键,如下所示:
2.2.3 :043 > h = {a: 1, b: 2, c: 2}
=> {:a=>1, :b=>2, :c=>2}
2.2.3 :044 > h.key(2)
=> :b
在您的情况下,ht.key(2924) == 2172
因为2172的因子之和也恰好是2924和2172 < 2620.
所以,没有红宝石虫存在。至于如何修复它,那就留给你了。
答案 1 :(得分:0)
7z
仅返回具有给定值的第一个键。你可以做点什么
Hash#key
并寻找密钥而不是值,因为密钥不能重复,而且它们是唯一可以信任的东西。