I am a newbie programming Ruby. I have the below code. Method sum_to_n? which takes an array of integers and an additional integer, n, as arguments and returns true if any two elements in the array of integers sum to n. It should return true for the empty array with zero argument, but keeps returning false.

def sum_to_n? (arr, n)
  hash = Hash.new(0)
  arr.each do |val|
   if hash.key? val
    return true
   else
    hash[n-val] = val
   end
end
return false

end

What am I doing wrong ?

The only return true is your code is on line 5. That line is inside the each, so it can only be reached if the array is not empty (otherwise the code in the each does not execute at all). If the array is empty it goes directly to line 10 and thus returns false.

If you want to return true for an empty array if the argument is zero, you need to add a check whether the array is empty and the argument zero and return true in that case.

If you also want to return true if the array contains the element n (and thus no adding is necessary), you could just append the element 0 to the array before the each. That way no special case would be necessary and sum_to_n?([],0), sum_to_n?([42],42) and sum_to_n?([23,13,7],13) would all be true (if that is indeed the intention).

Hi, where would you put the check in the code?

I have tried using :

if arr.nil? || arr.empty? 
    Return True 

and still same results ...

I cant figure out what is the issue yet. :(

That looks fine assuming the syntax errors (Return and True being capitalized) were just typos when copying the code here.

Where did you put the code? If you put it inside the each, it won't work because, as I said, the each won't run if the array is empty.

If you put it after the return false, it won't work because the method is done once return false is reached.

So put it at the beginning of the method and everything should be fine. If that does not work please post your current version of the code.

Note though that this will always return true if the array is empty - not just when n is 0. You should check for n being 0 as well to avoid this.

In theory, this is what I am trying to accomplish :

  1. If the array is empty, and n = 0, it should return true, but if the array is empty and n = 1 should return false.

puts sum_to_n?([],0) == True
puts sum_to_n?([],1) == False

2.If the items inside the array sum up to n, should return true, if not should return false.

puts sum_to_n?([1,1],2) == True
puts sum_to_n?)[1,1],3) == False

Here is my code :

Original Version.

def sum_to_n? (arr, n)
    hash = Hash.new
    arr.each do |val|
        if hash.key? val
            return true
        else
            hash[n-val] = val
        end
    end
    return false
end

It gives the following results :

puts sum_to_n?([],0) == false == wrong
puts sum_to_n?([],1) == false == correct
puts sum_to_n?([1,1],2) === true == correct
puts sum_to_n?([1,1],3) === false === correct

Version 1.

def sum_to_n? (arr, n)
    hash = Hash.new
    arr.each do |val|
        if arr.nil? || arr.empty?
            return true
        elif hash.key? val
            return true
        else
            hash[n-val] = val
        end
    end
    return false
end

It gives all false.

Version 2. This is correct, but not my code. Bit too advanced. :)

def sum_to_n?(arr, n)
  (arr.empty? && n.zero?) || arr.permutation(2).any? { |a, b| a + b == n }
end

puts sum_to_n?([],0) === Ture 
puts sum_to_n?([],1) === False
puts sum_to_n?([1,1],2) == True
puts sum_to_n?([1,1],3) == False 

Thanks for your patience, really appreciate it.

Okay the reason that the second code always returns false is that you misspelled elsif as elif. This way Ruby doesn't recognize that there's a second condition to be checked. Once you fix that, the behavior should be the same as the first code (i.e. still wrong) for the reason that I already explained.

Got it, so in Ruby doesnt recognize elif. But where would you put the check your refer to in my code ? If I use it in the following code, no issues :

def empty_array(arr)
    if arr.nil? || arr.empty?
        return true
    else
        return false
    end
end

puts empty_array([])
puts empty_array([1,1])

Right now put your each loop before return false and it'll work. The only thing left to do is to add the check for 0 to your if.

Thanks !!! It worked .... :D

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.