Reputation: 4103
I have an array:
x = [1,2,3,4,5]
I want to get:
output = [1,2,6,24,120]
Hope you see the pattern and what I want to accomplish here. x[1]
is
transformed into x[1]*x[0]
. x[2]
=> x[2]*x[1]*x[0]
, etc.
What's the most efficient way to do this in Ruby?
Upvotes: 1
Views: 384
Reputation: 1756
x.inject([]) do |result, arr_element|
last_num = result.last
result << (last_num.nil? ? arr_element : last_num * arr_element)
result
end
use inject and pass array as accumulator
Upvotes: 0
Reputation: 67850
This is a pretty general abstraction, usually called scanl in functional languages. A possible Ruby implementation:
module Enumerable
def scanl(&block)
self.inject([]) do |acc, x|
acc.concat([acc.empty? ? x : yield(acc.last, x)])
end
end
end
>> [1, 2, 3, 4, 5].scanl(&:*)
=> [1, 2, 6, 24, 120]
Upvotes: 1
Reputation: 83680
just for fun
[1,2,3,4,5].map.with_index{|a,i| ar[0,i+1].inject(:*)}
Upvotes: 0
Reputation: 20724
1.9.2 (main):0 > a
=> [1, 2, 3, 4, 5]
1.9.2 (main):0 > a.inject([]) {|arr, e| arr << a[0..arr.size].inject(:*) }
It's a nice way of doing it.
Upvotes: 1
Reputation: 11042
Here's how I'd do it
prev = 1
puts [1,2,3,4,5].map { |n| prev *= n }
Upvotes: 1
Reputation: 1238
arr = [1,2,3]
arr.each_with_index.map do |x,i|
arr[0..i].inject(1) { |total,y| total *= y } }
end
Upvotes: 1
Reputation: 41236
You'd probably want to make a recursive solution.
F(x) = if x < 1 return 0
else return A(x) * F(x - 1)
In the simplest mathematical form, where F is your result array, and A is your source array (with indices as x).
Upvotes: 0