Question

I am trying to find whether n exists as a sum of any two numbers in the passed array if so return true else false, the problem with my code is that inject is not iterating as I want it to. What am I doing wrong?

def sum_to_n?(array,n)
  array.each do |i|
    array.inject(i) do |memo,var|
      if memo + var == n
        return true
      else
        return false
      end
    end
  end
end

puts sum_to_n?([1,2,3,4,5],9)
Was it helpful?

Solution

Here is an approach :

def sum_to_n?(a,n)
  !!a.find{|e| a.include?(n-e)}
end
a = [1,2,3,4,5]
sum_to_n?(a,9) # => true
sum_to_n?(a,11) # => false

If you want to get those 2 elements:

def sum_to_n?(a,n)
  num=a.find{|e| a.include?(n-e)}
  unless num
    puts "not exist"
  else
    p [n-num,num]
  end
end
a = [1,2,3,4,5]
sum_to_n?(a,9)
# >> [5, 4]
sum_to_n?(a,11)
# >> not exist

Logic

Enumerable#find method passing one array element per iteration.Now for any iteration,say I have an element e,and I subtracted it from n. Now I was just testing that (n-e) is present in the source array.If I found a match #find will stop finding,and immediately will return e.If not found,then it will go for next iteration. If #find completes its iteration,but didn't find (n-e),as per the documentation it will return nil.

OTHER TIPS

This question have already be answered but I think this approach is more readable:

def sum_to_n?(a,n)
  a.combination(2).find{|x,y| x+y==n}
end

a = [1,2,3,4,5]
p sum_to_n?(a,9)  # => [4, 5]
p sum_to_n?(a,11) # => nil

Never one for doing things the easy way:

n = 14
a = [1,3,5,9,13,3,18]
if n==0
  a.select {|x| x == 0}.size > 1
else
  a.map {|x| 2*x - n}.uniq.group_by(&:abs).values.map(&:size).max > 1 # => true
end
  • for n != 0, double values and subtract n => [-12, -8, -4, 4, 12, -8, 22]. We are now looking for pairs that sum to zero.
  • uniq => [-12, -8, -4, 4, 12, 22] in case a has duplicates (the two 3's). Without uniq, we'd be in trouble at the next step.
  • group by absolute value => {12=>[-12, 12], 8=>[-8], 4=>[-4, 4], 22=>[22]}. Hash values of size 2 correspond to pairs that sum to n (1+13 => [-12,-12] and 5+9 => [-4, 4]).
  • select hash values, and map to .size => [2, 1, 2, 1], then see if [2, 1, 2, 1].max > 1.
arr = [1, 2,3,4,5,6,7]

num = 7  (given number for 2 element combination)

Below program will just return single combination

arr.uniq.combination(2).detect {|a, b| a + b == num}

=> [2, 5]

where as below program will return all possible combination

arr.uniq.combination(2).find_all {|a, b| a +b == num}

=> [[2, 5], [3, 4]]

RUBY

This code will reject the empty arrays and returns the proper array with values.

def find_sequence(val, num)
b = val.length (0..b - 1).map {|n| val.uniq.combination(n).each.find_all {|value| value.reduce(:+) == num}}.reject(&:empty?)
end

val = [-10, 1, -1, 2, 0] num = 2

Output will be [[2],[2,0],[-1,1,2],[-1,1,2,0]]

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top