R
Ragunathan Pattabiraman
Each eval is O(n-1). You do n of them.
I think eval I used in this case is constant time. Any other views?
I think eval I used in this case is constant time. Any other views?
Isn't it basically just iterating over the list and yielding? In which
case, your original loop:
will be interpreted as having a nested loop inside. So essentially
your running time is bound to n^2 - n, which is O(n^2)
input[0...index] + input[index+1..-1]
Isn't it basically just iterating over the list and yielding? In which
case, your original loop:will be interpreted as having a nested loop inside. So essentially
your running time is bound to n^2 - n, which is O(n^2)
each_index is iterating over and yielding, there we have the first loop.
But I am not sure how Ruby Array's [] is implemented when a range is
given. I will take a look when I get a chance (again there is JRuby,
IronRuby, and the native Ruby).
But isn't it safe to assume it would have optimized implementation done
by Ruby implementors than the ad hoc O(n) implementation?
time.
I checked Ruby 1.8.7 source code and Array[range] is done at constant
time. Here is the link to array.c
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_7/array.c?view=markup
IMHO you'd also look at join (iterates over the array) and eval
(parses the string). Eval is IMHO scary in this context because one
(most ruby users or I at least) usually doesn't really know what it
involves.
I think eval I used in this case is constant time. Any other views?
But simplicity is the virtue that is missing IMHO. I thought I would
attempt at simplicity. But as you pointed out it is not efficient at
all. ("It's another Ruby virtue" says Ruby critic!)
But simplicity is the virtue that is missing IMHO. I thought I would
attempt at simplicity. But as you pointed out it is not efficient at
all. ("It's another Ruby virtue" says Ruby critic!)
There's a very simple solution (which I think someone has posted
upthread). The idea is this: you calculate the partial products from
each end of the array. Then, e.g. product(all except x_10) =
product(x0..x9) * product(x11..x20). The code is straightforward, too
(but untested):
pre = []
post = []
prod = 1
n = ary.length - 1
0.upto(n) {|i|
prod *= ary
pre = prod
}
prod = 1
n.downto(0) {|i|
prod *= ary
post = prod
}
product_except = lambda {|i| pre[i-1] * post[i+1]}
Time complexity = O(n) to calculate pre, O(n) to calculate post and
O(1) to calculate product_except(i) for any i, O(n) to calculate them
all for a total of O(n).
martin
Kevin said:how bad is this?
inp = [4, 3, 2, 1, 2]
outp = []
inp.each_with_index {|val, idx| inp[idx] = 1; outp << inp.inject(1) { |prod,
val2| prod * val2 }; inp[idx] = val}
There's a very simple solution (which I think someone has posted
upthread). The idea is this: you calculate the partial products from
each end of the array. Then, e.g. product(all except x_10) =
product(x0..x9) * product(x11..x20). The code is straightforward, too
Ragunathan Pattabiraman said:Just wondering... is there any tool which computes the time complexity
given the code? That would be cool as we wouldn't want to checkout ruby
impl everytime.
yesteray said:You are evaluating a product of n-1 terms in each eval.
eval(3*2*1*2)
eval(4*2*1*2)
eval(4*3*1*2)
eval(4*3*2*2)
eval(4*3*2*1)
There is no way to optimize these multiplications away.
ex said:Hi guys, I wonder if someone can find a pure ruby solution instead of
mine (I still can get out of my *loop* mind):
################################################################################
# There is an array A[N] of N integers. You have to compose an array
# Output[N] such that Output will be equal to the product of all
# the elements of A[] except A.
#
# Example:
# INPUT:[4, 3, 2, 1, 2]
# OUTPUT:[12, 16, 24, 48, 24]
#
# Note: Solve it without the division operator and in O(n).
#===============================================================================
vals = [4, 3, 2, 1, 2]
front = []
back = []
mf = 1
mb = 1
for k in 0...vals.length
front.push(mf)
back.unshift(mb)
mf *= vals[k]
mb *= vals[vals.length - 1 - k]
end
ans = []
front.each_index{|k| ans.push(front[k]*back[k]) }
p vals
p ans
prod= lambda{|a| a.inject(1){|p,x| p*x}}
=> #<Proc:0xb7d708e0@(irb):1>
a=[4,3,2,1,2]
=> [4, 3, 2, 1, 2]
pa=[]
=> []
s=a.size
=> 5
s2=s-1
=> 4
# here is the meat:
# i just concat orig array so i don't need to rotate
# then get subarrays in groups of s2 (a.size-1)
a2=a+a
=> [4, 3, 2, 1, 2, 4, 3, 2, 1, 2]
1.upto(s) do |i|
pa << prod.call(a2[i,s2])
end
=> 1
################################################################################
# There is an array A[N] of N integers. You have to compose an array
# Output[N] such that Output will be equal to the product of all
# the elements of A[] except A.
#
# Example:
# INPUT:[4, 3, 2, 1, 2]
# OUTPUT:[12, 16, 24, 48, 24]
#
# Note: Solve it without the division operator and in O(n).
#===============================================================================
I have a humble suggestion to make for people who think they've solved this
problem in O(n) time: test it. Time it with 10 entries, 100 entries and
1000 entries in an array and see what happens. If the time used doesn't
increase roughly by an order of magnitude each time through and instead
shoots through the roof, you're not doing O(n).
[12, 16, 24, 48, 24]p pr.map{|x,y| x*y }
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.