简单的红宝石循环,以获得立方体的总和

时间:2014-06-23 01:17:18

标签: ruby

我被Ruby解决了这个问题:

计算给定范围a到b的立方体总和。编写一个名为sum_of_cubes的方法来完成此任务。

我写了这个:

def sum_of_cubes(a, b)
    sum = 0
    for x in a..b
        c = x ** 3
    end
    sum += c
end

我得到了b的立方体的值。这段代码有什么问题?如何通过简单的循环解决这个问题?

谢谢!

4 个答案:

答案 0 :(得分:8)

我会使用Enumerable#reduce

def sum_of_cubes min, max
  (min..max).reduce(0) { |a, b| a + b ** 3 }
end

对这里发生的事情的一点解释


我们从范围(min..max)开始,这是一个Enumerable

irb> (1..3).is_a? Enumerable
=> true

使用我们从reduce获得的Enumerable实例方法,我们可以使用为我们(可枚举)范围中的每个项调用的代码块,并最终返回单个值。

如果您认为"将我的项目组和减少为单个值,则函数名称是有意义的。"

这是我们的块

{ |a, b| a + b ** 3 }
  • 我们使用reduce调用0,这是 a param

    <的初始值 / LI>
  • 在后续调用中,块的返回值将传递给块的a参数

  • 范围内的每件商品都会传递到商品b param


让我们一步一步看看它是如何运作的

  1. (1..3).reduce(0) { |a, b| a + b ** 3 }

  2. 第一次阻止调用获得a=0(初始值)和b=1(我们范围内的第一项)

    我们块的返回值为0 + 1 ** 31

  3. 第二次阻止调用获得a=1(上次通话的返回值)和b=2(我们范围内的第二项)

    我们块的返回值为1 + 2 ** 39

  4. 第三次阻止调用获得a=9(上一次调用的返回值)和b=3(我们范围内的第三项和最后一项)

    我们块的返回值为9 + 3 ** 336

  5. reduce的最终返回值是最后一次调用的块的返回值

    在这种情况下36

答案 1 :(得分:3)

您需要在循环内部sum += c 。完成后返回sum

答案 2 :(得分:3)

这是另一种计算方法。它没有解决你的循环问题,但我认为值得一提。

整数13 + 23 + 33 + ... + n3的立方体总和由公式(n(n + 1)/2)2给出,因此给定范围 min..max的多维数据集总和由下式给出: :

(max(max + 1)/2)2 - ((min-1)((min-1) + 1)/2)2

在代码中,这可能看起来像:

def sum_of_cubes_fixed min, max
  lower = min - 1
  (((max * (max + 1))/2) ** 2) - (((lower * (lower + 1))/2) ** 2)
end

这段代码避免了循环,因此O(1)而不是O(n)(差不多 - 我在这里挥手一点,乘法和取幂的时间复杂度将取决于数字的大小)。对于小尺寸范围,您不会注意到这一点,但对于较大尺寸,这与环形版本之间的差异变得越来越明显。我没有做过任何严格的基准测试,但使用reduce方法在1到10,000,000范围内对我的机器进行快速测试需要几秒钟,但这种方法几乎是即时的。

通常我只会使用reduce这样的东西,但任务的结构表明可能有更好的方法。在谷歌的帮助下,我找到了这个公式并提出了一个更有效的解决方案(至少对于大范围)。

答案 3 :(得分:3)

(a..b).map{|i| i**3 }.inject(&:+) map and inject完美地完成了工作。

编辑:虽然它遍历列表两次;)