好的。我认为我有正确的想法找到欧拉#23的解决方案(关于找到所有数字的总和,不能表示为两个丰富数字的总和)。
然而,显然我的一种方法太残忍了。 你是如何强迫这一点并让它发挥作用的呢?
sum_of_two_abunds?(num, array)
是有问题的方法。我已经尝试过预先排除某些数字,它仍然需要永远,我甚至不确定它是否给出了正确的答案。
def divsum(number)
divsum = 1
(2..Math.sqrt(number)).each {|i| divsum += i + number/i if number % i == 0}
divsum -= Math.sqrt(number) if Math.sqrt(number).integer?
divsum
end
def is_abundant?(num)
return true if divsum(num) > num
return false
end
def get_abundants(uptonum)
abundants = (12..uptonum).select {|int| is_abundant?(int)}
end
def sum_of_two_abunds?(num, array)
#abundant, and can be made from adding two abundant numbers.
array.each do |abun1|
array.each do |abun2|
current = abun1+abun2
break if current > num
return true if current == num
end
end
return false
end
def non_abundant_sum
ceiling = 28123
sum = (1..23).inject(:+) + (24..ceiling).select{|i| i < 945 && i % 2 != 0}.inject(:+)
numeri = (24..ceiling).to_a
numeri.delete_if {|i| i < 945 && i % 2 != 0}
numeri.delete_if {|i| i % 100 == 0}
abundants = get_abundants(ceiling)
numeri.each {|numerus| sum += numerus if sum_of_two_abunds?(numerus, abundants) == false}
return sum
end
start_time = Time.now
puts non_abundant_sum
#Not enough numbers getting excluded from the total.
duration = Time.now - start_time
puts "Took #{duration} s "
答案 0 :(得分:2)
提高速度的简单方法是加快sum_of_two_abunds?
方法:
def sum_of_two_abunds?(num, array)
array.each do |abun1|
array.each do |abun2|
current = abun1+abun2
break if current > num
return true if current == num
end
end
return false
end
代替内部循环,只需询问数组是否包含num - abun1
:
def sum_of_two_abunds?(num, array)
array.each do |abun1|
return true if array.include?(num - abun1)
end
false
end
这已经比Ruby代码快,因为它更简单,运行速度更快的C代码。此外,既然这个想法很清楚,你可以利用数组进行排序并使用二进制搜索搜索num - abun1
的事实:
def sum_of_two_abunds?(num, array)
array.each do |abun1|
return true if array.bsearch { |x| num - abun1 <=> x }
end
false
end
制作Rubyish:
def sum_of_two_abunds?(num, array)
array.any? do |abun1|
array.bsearch { |x| num - abun1 <=> x }
end
end
现在您可以摆脱自己的特殊情况优化并修复错误的divsum
(例如声称divsum(4)
是5
...你应该真的与天真的比较没有尝试任何平方根优化的实现。)
然后它应该在一分钟内完成(在我的电脑上大约11秒)。
或者你可以完全抛弃sum_of_two_abunds?
而只是创造两个丰度的所有总和,并使他们对总和的贡献无效:
def non_abundant_sum
ceiling = 28123
abundants = get_abundants(ceiling)
numeri = (0..ceiling).to_a
abundants.each { |a| abundants.each { |b| numeri[a + b] = 0 } }
numeri.compact.sum
end
在我的电脑上运行大约3秒钟。