Sam P
Sam P

Reputation: 117

How do you split a ruby array into two arrays based on index?

So I have an array of integers. I'm trying to take that array and find an index N where the sum of the integers to the left of N is equal to the sum of the integers to the right of N. If there is no index that would make this happen, return -1.

For example:

Let's say I have an array [1,2,3,4,3,2,1]: I want the method to return the index 3, because at the 3rd position of the array, the sum of left side of the index and the sum of the right side of the index both equal 6:

[1,2,3].sum #=> 6
[3,2,1].sum #=> 6

For the array [1,100,50,-51,1,1] it should return the index 1, because at the 1st position of the array, the sum of left side of the index [1].sum and the sum of the right side of the index [50,-51,1,1].sum both equal 1.

Last one:

I have an array [20,10,-80,10,10,15,35] At index 0 the left side is [], and the right side is [10,-80,10,10,15,35]. They both are equal to 0 when added. (Empty arrays are equal to 0).

Index 0 is the place where the left side and right side are equal.

Assuming the arrays are all integers of length between 0 and 1000, and the numbers can be any integer positive or negative.

The lowest index N where the side to the left of N is equal to the side to the right of N. If it doesn't have an index that fits these rules, then it returns -1.

If an array has multiple answers, it returns the lowest correct index. I started out like this but nothing I tried gave me the result I was looking for.

def find_even_index(arr)
  if arr.size > 1
    left_side = #some code to get left side #reduce(:+)
    right_side = #some code to get right side #reduce(:+)
    # something that gives index at which sum of left side is the same as right
  elsif
    # more than one result give lowest index
  else
    return -1 
  end
end

Thanks!

Upvotes: 0

Views: 315

Answers (2)

Cary Swoveland
Cary Swoveland

Reputation: 110675

Here is another way to do that.

def idx(arr)
  tot = arr.sum
  arr.each_index.reduce(0) do |left_tot, i|
    m = arr[i]
    return i if left_tot == tot - m
    left_tot += 2*m
  end && -1
end
idx [1, 2, 3, 4, 3, 2, 1]
  #=> 3
idx [1, 100, 50, -51, 1, 1]
  #=> 1
idx [20, 10, -80, 10, 10, 15, 35]
  #=> 0
idx [20, 10, -15, 3]
  #=> -1

Upvotes: 2

Pavel Mikhailyuk
Pavel Mikhailyuk

Reputation: 2877

def eq_sum_index(arr)
  right_sum = arr.sum
  left_sum = 0
  arr.each_with_index do |e, index|
    right_sum -= e
    return index if left_sum == right_sum
    left_sum += e
  end
  -1
end

eq_sum_index([1, 2, 3, 4, 3, 2, 1])
# => 3
eq_sum_index([1, 100, 50, -51, 1, 1])
# => 1
eq_sum_index([20, 10, -80, 10, 10, 15, 35])
# => 0

Explanation:

  1. Pre-calculate right part sum as sum of the array.
  2. Iterate array, each turn transfer elements from the right part to the left one (subtract from the right and add to the left)
  3. Each turn, return index if two sums are equal.
  4. Return -1 if no equal sums were found.

Upvotes: 2

Related Questions