如何找到阶乘的总和
How to find the sum of factorials
使用 minitest,我试图让这个测试通过,它要求 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}
有没有人愿意解释更清晰、更简单的解决方案?
def sum_of_factorials(n)
(1..n).reduce([1, 0]) { |(f, sum), e| [(f *= e), (sum + f)] }.last
end
生产
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
既然可以写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.drop(1).reverse_each { |i| sum_of_factorials = 1 + i * sum_of_factorials }
您似乎得到了:
def test_sum_of_factorials
sum_of_factorials = 0
numbers = [1, 2, 3, 4, 5]
<...missing bits...>
assert_equal 153, sum_of_factorials
end
并被要求填写缺失的位。我认为正在要求类似以下内容。
def test_sum_of_factorials
sum_of_factorials = 0
numbers = [1, 2, 3, 4, 5]
fac = 1
numbers.each do |n|
fac *= n
sum_of_factorials += fac
end
assert_equal 153, sum_of_factorials
end
我们可以这样写:
def test_sum_of_factorials
numbers = [1, 2, 3, 4, 5]
assert_equal 153, sum_of_factorials(numbers)
end
def sum_of_factorials(numbers)
fac_sum = 0
fac = 1
numbers.each do |n|
fac *= n
fac_sum += fac
end
fac_sum
end
哪里
sum_of_factorials([1,2,3,4,5])
#=> 153
要多Ruby-like,不过,用Array#sum写sum_of_factorials
如下:
def sum_of_factorials(numbers)
fac = 1
numbers.sum { |n| fac *= n }
end
连同您的问题标题,这就是为什么其他答案的作者假设您在询问如何改进方法 sum_of_factorials
的原因。首先,它可以传递参数 numbers.max
,而不是数组 numbers
.
另一种写 sum_of_factorials
的方法是使用方法 Enumerator::produce,它在 v2.7 中首次亮相。
def sum_of_factorials(n)
enum = Enumerator.produce([1,1]) { |n0, n1| [n0+1, (n0+1)*n1] }
n.times.sum { enum.next.last }
end
(1..8).each { |n| puts "%d: %6d" % [n, sum_of_factorials(n)] }
1: 1
2: 3
3: 9
4: 33
5: 153
6: 873
7: 5913
8: 46233
注意如果:
enum = Enumerator.produce([1,1]) { |n0, n1| [n0+1, (n0+1)*n1] }
#=> #<Enumerator: #<Enumerator::Producer:0x000059d490c742a0>:each>
然后
enum.next #=> [1, 1]
enum.next #=> [2, 2]
enum.next #=> [3, 6]
enum.next #=> [4, 24]
所以 1
到 4
的阶乘由下式给出(在重新定义或倒带 enum
之后):
enum.next.last #=> 1
enum.next.last #=> 2
enum.next.last #=> 6
enum.next.last #=> 24
如果 n
可以等于零,请在方法开头添加行 return 1 if n.zero?
。
另一种选择是定义阶乘函数(此处被盗:),可能作为 Integer
class:
的补丁
module MyMathFunctions
def factorial
(1..self).reduce(1, :*)
end
end
Integer.include MyMathFunctions
所以你可以这样使用它:10.factorial #=> 3628800
然后,调用:
[1, 2, 3, 4, 5].sum &:factorial
#=> 153
我想简单的如下,
[1, 2, 3, 4, 5].map { |x| (1..x).inject(1, :*) }.sum
# => 153
使用 minitest,我试图让这个测试通过,它要求 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}
有没有人愿意解释更清晰、更简单的解决方案?
def sum_of_factorials(n)
(1..n).reduce([1, 0]) { |(f, sum), e| [(f *= e), (sum + f)] }.last
end
生产
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
既然可以写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.drop(1).reverse_each { |i| sum_of_factorials = 1 + i * sum_of_factorials }
您似乎得到了:
def test_sum_of_factorials
sum_of_factorials = 0
numbers = [1, 2, 3, 4, 5]
<...missing bits...>
assert_equal 153, sum_of_factorials
end
并被要求填写缺失的位。我认为正在要求类似以下内容。
def test_sum_of_factorials
sum_of_factorials = 0
numbers = [1, 2, 3, 4, 5]
fac = 1
numbers.each do |n|
fac *= n
sum_of_factorials += fac
end
assert_equal 153, sum_of_factorials
end
我们可以这样写:
def test_sum_of_factorials
numbers = [1, 2, 3, 4, 5]
assert_equal 153, sum_of_factorials(numbers)
end
def sum_of_factorials(numbers)
fac_sum = 0
fac = 1
numbers.each do |n|
fac *= n
fac_sum += fac
end
fac_sum
end
哪里
sum_of_factorials([1,2,3,4,5])
#=> 153
要多Ruby-like,不过,用Array#sum写sum_of_factorials
如下:
def sum_of_factorials(numbers)
fac = 1
numbers.sum { |n| fac *= n }
end
连同您的问题标题,这就是为什么其他答案的作者假设您在询问如何改进方法 sum_of_factorials
的原因。首先,它可以传递参数 numbers.max
,而不是数组 numbers
.
另一种写 sum_of_factorials
的方法是使用方法 Enumerator::produce,它在 v2.7 中首次亮相。
def sum_of_factorials(n)
enum = Enumerator.produce([1,1]) { |n0, n1| [n0+1, (n0+1)*n1] }
n.times.sum { enum.next.last }
end
(1..8).each { |n| puts "%d: %6d" % [n, sum_of_factorials(n)] }
1: 1
2: 3
3: 9
4: 33
5: 153
6: 873
7: 5913
8: 46233
注意如果:
enum = Enumerator.produce([1,1]) { |n0, n1| [n0+1, (n0+1)*n1] }
#=> #<Enumerator: #<Enumerator::Producer:0x000059d490c742a0>:each>
然后
enum.next #=> [1, 1]
enum.next #=> [2, 2]
enum.next #=> [3, 6]
enum.next #=> [4, 24]
所以 1
到 4
的阶乘由下式给出(在重新定义或倒带 enum
之后):
enum.next.last #=> 1
enum.next.last #=> 2
enum.next.last #=> 6
enum.next.last #=> 24
如果 n
可以等于零,请在方法开头添加行 return 1 if n.zero?
。
另一种选择是定义阶乘函数(此处被盗:),可能作为 Integer
class:
module MyMathFunctions
def factorial
(1..self).reduce(1, :*)
end
end
Integer.include MyMathFunctions
所以你可以这样使用它:10.factorial #=> 3628800
然后,调用:
[1, 2, 3, 4, 5].sum &:factorial
#=> 153
我想简单的如下,
[1, 2, 3, 4, 5].map { |x| (1..x).inject(1, :*) }.sum
# => 153