是否有更好的方法来查找阶乘之和?

问题描述 投票:0回答:3

使用最小测试,我正在尝试使测试波纹管通过,要求总和为5!

def test_sum_of_factorials

  sum_of_factorials = 0
  numbers = [1, 2, 3, 4, 5]


  assert_equal 153, sum_of_factorials
end

我已经写了一个合格的解决方案,但是它又长又重复​​:

    fractorial_5 = numbers.inject(1) {|aggregate, num| aggregate * num}
    fractorial_4 = numbers[0..3].inject(1) {|aggregate, num| aggregate * num}
    fractorial_3 = numbers[0..2].inject(1) {|aggregate, num| aggregate * num}
    fractorial_2 = numbers[0..1].inject(1) {|aggregate, num| aggregate * num}
    fractorial_1 = 1

    fractorials_array = [fractorial_1, fractorial_2, fractorial_3, fractorial_4, fractorial_5]

    fractorials_array.each {|fractorial| sum_of_factorials += fractorial}

有人愿意解释的更干净,更简单的解决方案吗?

ruby minitest
3个回答
0
投票

我会这样写:

(1..5).sum{ |n| (1..n).inject(1, :*) }
#=> 153

0
投票
def sum_of_factorials(n)
  (1..n).reduce([1, 0]) { |(f, sum), e| [(f *= e), (sum + f)] }.last
end

产生

pry(main)> sum_of_factorials(5)
=> 153

说明:

def sum_of_factorials(n)
  (1..n).             # n times
    reduce([1, 0]) do # iterate and use [factorial, sum] as an accumulator
    |(f, sum), e|     # splat the accumulator into f and sum variables
      [               # each time recalculate the accumulator as
        f *= e,       # product of the element and previous factorial,
        sum + f       # sum of current factorial and previous sum
      ]
    end.last          # and return only last part(sum) of the accumulator
end

0
投票

由于您可以写5!+4!+3!+2!+1 !,通常为1!+2!+3!+ ... + n!作为1 + 2(1 + 3(1 + 4(1 + 5(1 + ...(1 + n)))))),您可以在O(n)]中执行此操作

sum_of_factorials = 1
numbers.reverse_each { |i| sum_of_factorials = 1 + i * sum_of_factorials }
© www.soinside.com 2019 - 2024. All rights reserved.