Search code examples
rubynullintegerruntime-error

Codility error: Invalid result type, Integer expected, NilClass found


EDIT: SOLVED BY STEFAN BUT: Now, the only questions left are: Why has the shorter solution such a poor performance (results: 100%, performance: 32%, result: 66%) , while the longer version performs a bit better but seems to produce worse results (60%, 50%, 55%)?

Start of original question: I'm currently trying the Codility demo test and the problem to solve is to find the lowest integer above 0 that's not included in a given array. This is my code in two different versions with the same result. The output is right but the compiler throws the abovementioned error, resulting in the test failing. This seems to be a common error on Codility, when looking up this error here on SO.

# you can write to stdout for debugging purposes, e.g.
# puts "this is a debug message"

def solution(a)
  # write your code in Ruby 2.2
  num = 1
  a=a.sort
  a.uniq!
  a.each do |x|
    if x == num then
      num += 1
      next
    else
      break
    end
  end
  puts num
end

or

def solution(a)
  # write your code in Ruby 2.2
  num = 1
  while a.include?(num) do
    num += 1
  end
  puts num
end

results in:

Compilation successful.

Example test:   [1, 3, 6, 4, 1, 2]
Output (stderr):
Invalid result type, Integer expected, NilClass found
Output:
5
RUNTIME ERROR (tested program terminated with exit code 1)

Example test:   [1, 2, 3]
Output (stderr):
Invalid result type, Integer expected, NilClass found
Output:
4
RUNTIME ERROR (tested program terminated with exit code 1)

Example test:   [-1, -3]
Output (stderr):
Invalid result type, Integer expected, NilClass found
Output:
1
RUNTIME ERROR (tested program terminated with exit code 1)

Producing output might cause your solution to fail performance tests.
You should remove code that produces output before you submit your solution.

Detected some errors.

I really don't understand what's wrong. The array only contains integers, num is an integer, everything is an integer but the compiler says it's NIL. What can I do?

EDIT: The same code runs without errors in the SoloLearn app and on my local machine.


Solution

  • The output is right but the compiler throws the abovementioned error, resulting in the test failing

    Although puts generates output it has a return value of nil:

    puts 123
    # 123      # <- output
    #=> nil    # <- return value
    

    I assume that your method is supposed to return the value instead just printing it to standard out.

    You can fix this by removing puts in your method's last line:

    def solution(a)
      num = 1
      while a.include?(num)
        num += 1
      end
      num # <- without "puts"
    end
    

    To generate debug output you could add puts num on a separate line before the return value, e.g.:

    def solution(a)
      # ...
    
      puts num  # <- prints num
      num       # <- returns num
    end
    

    or you could use p which outputs the object's inspect value and returns the object:

    def solution(a)
      # ...
    
      p num  # <- prints num.inspect and returns num
    end
    

    Regarding the performance: try to understand what the code has to do in order to get the result. The "short" solution increments num and checks whether it is included in the array. But an inclusion check has to traverse the array (at least up to the matching element). So for each increment of num, you are traversing the array from the beginning.

    You can speed this up significantly by utilizing Set for the lookup:

    require 'set'
    
    def solution(a)
      set = Set.new(a)
      num = 1
      num += 1 while set.include?(num)
      num
    end