Search code examples
rubyrecursionmergesort

Ruby "ArgumentError: comparison of Fixnum with Array failed"


I'm attempting to implement a Ruby merge sort algorithm, and it seems to me from staring at it for awhile that the program should work. However, I'm getting the error listed in the title and I'm not quite sure why. Any assistance would be greatly appreciated

Full code:

def merge_sort(arr)
    return arr if arr.length == 1
    mid = arr.length/2
    left = merge_sort(arr[0..mid-1])
    right = merge_sort(arr[mid..-1])
    merge(left,right)
end

def merge(arr1,arr2,merged=[])

    i=0 #arr1 initialize
    j=0 #arr2 initialize
    while i < arr1.length || j < arr2.length
        if i < arr1.length && j<arr2.length
            if arr1[i] <= arr2[j]
                merged << arr1[i]
                i+=1
            else
                merged << arr2[j]
                j+=1
            end
        elsif i<arr1.length
            merged << arr1[i..-1]
            i=arr1.length
        elsif j<arr2.length
            merged << arr2[j..-1]
            j=arr2.length
        end
    end
    merged
end


array = [10,9,8,7,6,5,4,3,2,1]
p merge_sort(array)

Error:

$ ruby mergeSort.rb 
mergeSort.rb:15:in `<=': comparison of Fixnum with Array failed (ArgumentError)
    from mergeSort.rb:15:in `merge'
    from mergeSort.rb:6:in `merge_sort'
    from mergeSort.rb:5:in `merge_sort'
    from mergeSort.rb:4:in `merge_sort'
    from mergeSort.rb:36:in `<main>'

Note: here is line 15

if arr1[i] <= arr2[j]


Solution

  • The problem is that you are pushing arrays into arrays by calling << in

    elsif i<arr1.length
      merged << arr1[i..-1]
      i=arr1.length
    elsif j<arr2.length
      merged << arr2[j..-1]
      j=arr2.length
    end
    

    and that creates unwanted nested arrays. When you compare array elements by arr1[i] <= arr2[j], the elements of arr1 and arr2 are not necessarily at the same nested level (i.e., they may be an array or not an array). That causes the error.

    If you change the << in the part above to concat, then it will work.