Question

In Ruby, I would like to take an array of numbers, select 2 different numbers, add those 2 numbers together and see weather there equal to a variable x.y'd a variable x. Here is the code I used

def arrayIsEqual? (numArray, x)
  return true if numArray.sample + numArray.sample == x
  return false if numArray.empty? || numArray.count == 1
end

for example

numArray = [4,2,7,5]
x = 11

arrayIsEqual (numArray, n) should return true, since 4 + 7 = n(11)

How do I get this to work?

I don't want it to be 2 random numbers, just any 2 different numbers that add up to n

Was it helpful?

Solution

It looks like you're trying to see if there are any two numbers in the array that add up to the specified value x. However, your code just picks two numbers at random and checks if those numbers add up.

Ruby has the Array#combination method, which generates all combinations of a given length:

def contains_pair_for_sum?(arr, n)
  !!arr.uniq.combination(2).detect { |a, b| a + b == n }
end

A few things to note:

  • First, we named it according to Ruby conventions: each word is separated_by_underscores. The ? on the end means that the method is a predicate method and returns a true or false value.

  • Inside the method, a few things happen. Let's look at that line, piece by piece.

    • arr: We take the array that was passed in.

    • <...>.uniq: We only look at the unique elements (because the OP wants to pick two different numbers).

    • <...>.combination(2): We ask for all combinations from the array of length 2. If the array was [4, 5, 6], we'd get [[4, 5], [4, 6], [5, 6]].

    • <...>.detect { |a, b| a + b == n }: We look for the first combination that adds up to n. If we found one, that's the result of that method. Otherwise, we get nil.

    • !!<...>: Finally, we take the result we got from detect and negate it twice. The first negation produces a Boolean value (true if the value we got was nil, or false if it's anything else); the second negation produces a Boolean value that's identical to the truth value of the first negation. This is a Ruby idiom to coerce a result into being either true or false.

Let's see it in action:

array = [4, 5, 9, 7, 8]

contains_pair_for_sum?(array, 11)
# => true (because [4, 7] sums to 11)

contains_pair_for_sum?(array, 17)
# => true (because [9, 8] sums to 17)

contains_pair_for_sum?(array, 100)
# => false (no pair matched)

OTHER TIPS

I understand that your question is "is there any pair of numbers in my array equals x", in which case this will do what you need:

def has_pair_equal?(num_array, x)
  (0..num_array.length-1).any? do |i| 
    num_array[i+1..-1].any? { |n| n + num_array[i] == x }
  end
end

This checks all sums of pairs of numbers in the array, and checks if their sum is x. sample randomly picks an item from the array, which means that what your code does is "return true sometimes if there is a pair of numbers in my array equals x"

def array_is_equal? (num_array, x) 
  equality = 0
  num_array.each do |a|
    equality += 1 if a == x
    return true if equality == 2
  end
  return false
end

Use lowercase and underscores for variables in Ruby. The convention is different here than in some other languages.

One liner

x=[4,2,7,5]; x.each_with_index.any? {|y,i| x.each_with_index.any? {|z,j| unless i==j; z+y==11; end } }

And as a function

def pair_sum_match?(arr, x)
    arr.each_with_index.any? do |y,i|
        arr.each_with_index.any? do |z,j|
            unless i==j
                z+y==x
            end
        end
    end
end

Updated: Added each_with_index to avoid self inclusion on checks. It's a lot longer now :-/

Just iterate over it once and use the target number to see if it matches. 100 times faster then most of the answers here

numbers = ( -10..10 ).to_a
numbers.unshift( numbers.first + -1 ) # if you do -20 or 20
numbers.push( numbers.last + 1 )
target    = 5
searched  = { }
matches   = { }
numbers.each do |number|
  if searched[ target - number + 1 ] == true
    matches[ "#{ number }_plus_#{ target - number }" ] = target
  end
  searched[ number + 1 ] = true
end
ap matches
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top