I have an amount. I want to iterate the array starting from the first value and if I add the next value and it equals amount then those two values in the array should be re
Try this:
array = [1,2,3,4,7]
amount = 17
master_array = (1..array.size).map { |i| array.each_slice(i).to_a }
master_array.each.with_index do |e,i|
p e[0] if master_array[i][0].inject(:+) == amount
end
arr = [1,2,3,4,7]
tot = 6
Case 1: The elements to be summed are the first n
elements of the array
Not very efficient, but reads well:
idx = arr.size.times.find { |i| arr[0..i].reduce(:+) == tot }
idx ? arr[0..idx] : nil
#=> [1, 2, 3]
More efficient:
t = 0
idx = arr.size.times.find { |i| t += arr[i]; t == tot }
idx ? arr[0..idx] : nil
#=> [1, 2, 3]
Use recursion
def partial_sum(arr, remaining)
return nil if arr.empty?
first, *rest = arr
if remaining == first
[first]
else
ret = partial_sum(rest, remaining-first)
ret ? [first, *ret] : nil
end
end
partial_sum(arr, 6)
#=> [1, 2, 3]
partial_sum(arr, 7)
#=> nil
Case 2: the elements to be summed can be any elements of the array
def sum_subarrays(arr, tot)
(0...arr.size).each do |n|
b = arr.combination(n).find { |a| a.reduce(:+) == tot }
b ? (return b) : nil
end
nil
end
(1..17).each do |tot|
v = sum_subarrays(arr, tot)
puts "sum_subarrays(arr, #{tot}) = #{v ? v : 'nil'}"
end
sum_subarrays(arr, 1) = [1]
sum_subarrays(arr, 2) = [2]
sum_subarrays(arr, 3) = [3]
sum_subarrays(arr, 4) = [4]
sum_subarrays(arr, 5) = [1, 4]
sum_subarrays(arr, 6) = [2, 4]
sum_subarrays(arr, 7) = [7]
sum_subarrays(arr, 8) = [1, 7]
sum_subarrays(arr, 9) = [2, 7]
sum_subarrays(arr, 10) = [3, 7]
sum_subarrays(arr, 11) = [4, 7]
sum_subarrays(arr, 12) = [1, 4, 7]
sum_subarrays(arr, 13) = [2, 4, 7]
sum_subarrays(arr, 14) = [3, 4, 7]
sum_subarrays(arr, 15) = [1, 3, 4, 7]
sum_subarrays(arr, 16) = [2, 3, 4, 7]
sum_subarrays(arr, 17) = nil