0

I spent a bit of time today tackling the equilibrium index problem (described here)

After writing my own solution (which performed badly with large numbers), I decided to find one that would be a perfect score. I found this (which Codility scores as 100/100):

  def equi(a)
    left, right = 0, a.inject(0, &:+)
    indices = []
    a.each_with_index do |val, i|
      right -= val

      indices << i if right == left

      left += val
    end
    indices
  end

What I don't understand is the piece of parallel assignment and use of inject at the top of the method. Is anyone able to describe what this is doing?

Many thanks! Stu

Stu
  • 154
  • 1
  • 11

2 Answers2

2

It assigns 0 to left and the sum of a's elements to right. The 0 argument is there because otherwise an empty array would return nil. The shorthand used for summing is Symbol#to_proc and is unnecessary because inject directly takes a symbol as its argument - inject(0, :+).

KL-7
  • 46,000
  • 9
  • 87
  • 74
Michael Kohl
  • 66,324
  • 14
  • 138
  • 158
  • Thanks a lot for the explanation @Michael Kohl. I need to read up on parallel assignment. One thing that made this extra weird is that, when I stuck a debugger after the assignment line, the values of 'left' and 'right' are both 0. Shouldn't I expect 'right' to be the sum of the vals in the array at that stage? Or is it evaluated later on? – Stu Jun 23 '12 at 11:46
  • Parallel assignment isn't exactly special. `right` should only be 0 if `a` is empty though. – Michael Kohl Jun 23 '12 at 12:04
0

It's just a sum of the array:

>> ar = (1..10).to_a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
>> ar.inject(0, &:+)
=> 55 
# or a shorter version
>> ar.inject(&:+)
=> 55

You should really read the doc on the Enumerable#inject method. It explains everything.

KL-7
  • 46,000
  • 9
  • 87
  • 74