让我们说我们需要从(0..999_999_999)
的范围中提取值。我们需要为条件语句返回true的所有数字的 sum 。例如,那些序列为" 123"数字末尾的数字。
在没有循环的情况下获得此总和的最快方法是什么?
编辑:条件语句可以是任何语句,例如n.to_s.chars.map {| d | d = d.to_i} .inject(:+)%12345 == 0其中n是范围内的数字。
Edit2:这是我遇到问题的代码:
def find_all(n, k)
arr = []
lower_limit = ("1" + "0" * (k - 1)).to_i
upper_limit = ("9" * k).to_i
while lower_limit <= upper_limit
if lower_limit.to_s.chars == lower_limit.to_s.chars.sort && lower_limit.to_s.chars.map{|v| v = v.to_i}.inject(:+) == n
arr << lower_limit
end
lower_limit += 1
end
arr.empty? ? [] : [arr.size, arr.min, arr.max]
end
其中n
是所有数字的总和,k
是数字中的数字位数。
我的代码应该在不到12000毫秒的时间内在服务器上运行,并且k
数量非常多,且(n,k)
不同。即使我的代码有效,但它的算法太慢,循环不会导致成功。
答案 0 :(得分:2)
范围是
r = 0..10**9-1
r.size
#=> 1_000_000_000 (10**9)
对于任何给定的最后三位数,此范围包含以这三位数结尾的10**6
个数字。假设最后三位数是000
。然后,这些数字的总和将是0..10**6-1
范围内的数字乘以10**3
的总和:
s = (10**3) * (0 + 10**6-1)*(10**6)/2
#=> 499999500000000
如果此总和中每个10**6
数字的后三位数为123
,而不是000
,则123
将添加到每个数字中。因此,结束123
的数字之和为
s + 123 * (10**6)
#=> 499999746000000