Похоже, вам дано:
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 -подобно, однако, использовать 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 :: производить, который дебютировал в 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?
в начале метода.