Charles Cruz
Charles Cruz

Reputation: 33

Ruby: Continue adding each value in an array until it reaches the max set value

I can't think of a way on how to sum up the values inside the given array and stops when it reaches the max value. Like the example on below, it should add only 60 and 80. The array could be more than 3 values.

def sum (array, max_value)
  #code here
end

puts sum([60, 80, 90], 200)

Upvotes: 1

Views: 808

Answers (3)

dawg
dawg

Reputation: 103774

Ruby is not my first language, but you could do a simple loop:

def msum(arr,m)
    i=0
    sum=0
    arr.each do |e| 
        sum+=e
        break if sum>m
        i+=1
    end
    return arr.take(i)
end

Upvotes: -1

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

add = ->(arr, max, current = 0) do
  val = arr.shift
  arr.empty? || val + current > max ? \
    current : add(arr, max, val + current)
end
add.([60, 80, 90], 200)
#⇒ 140

The prevent a mutation of the original array, when passed by reference, one should dup it in advance:

arr, max = [60, 80, 90], 200
add.(arr.dup, max)

FWIW: the solution that does not mutate an input:

add = lambda do |arr, max, current = 0, entry = true|
  arr = arr.dup if entry
  val = arr.shift
  arr.empty? || val + current > max ? \
    current : add(arr, max, val + current, false)
end

Upvotes: 2

tadman
tadman

Reputation: 211560

You can always just cap it with inject:

def sum(array, max_value)
  array.inject do |s, v|
    s + v <= max_value ? s + v : s
  end
end

Since you have control over what value is chained forward, you can stop adding to the sum if it'd exceed your threshold.

Edit: If you're looking for this to break out on longer lists:

def sum (array, max_value)
  array.inject do |s, v|
    break s if s + v > max_value

    s + v
  end
end

Upvotes: 3

Related Questions