在Ruby中不循环地提取值

时间:2017-04-23 19:09:51

标签: ruby

让我们说我们需要从(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)不同。即使我的代码有效,但它的算法太慢,循环不会导致成功。

1 个答案:

答案 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