Search code examples
rubyalgorithmsortingquicksort

Ruby Stack Level Too Deep Error


I'm adapting some code from Python into Ruby, which defines a #partition method and a #quicksort method. I'm running into a "Stack Level Too Deep" error due to the enumerable in the #partition method:

(low..high).map do |j| 

The #partition method works find on its own, so I'm not sure if I have the right enumerable or not, and any suggestions would be greatly appreciated. (Also, I know Ruby has a #partition method; this is just for curiosity, on my part.) Thanks!

# This function takes last element as pivot, places
# the pivot element at its correct position in sorted
# array, and places all smaller (smaller than pivot)
# to left of pivot and all greater elements to right
# of pivot

def partition(arr, low, high)
  i = low - 1   #index of smaller element
  pivot = arr[high]   #pivot

  (low..high).map do |j|
    #if current element is smaller than or equal to pivot
    if arr[j] <= pivot
      #increment index of smaller element
      i = i + 1
      arr[i], arr[j] = arr[j], arr[i]
    end
  end
  arr[i+1], arr[high] = arr[high], arr[i+1]
  return i+1
end

def quicksort(arr, low, high)
  if low < high
    pi = partition(arr, low, high)
    quicksort(arr, low, pi-1)
    quicksort(arr, pi+1, high)
  end
end

Solution

  • Try (low..high-1).each do |j|.

    Or even better: (low...high).each do |j| as steenslag pointed out.

    This is because Python breaks the loop one step before.

    arr = [10, 7, 8, 9, 1, 5]
    n = arr.size
    quicksort(arr, 0, n-1)
    
    p arr # => [1, 5, 7, 8, 9, 10]
    

    This loop in Ruby breaks at 10

    (0..10).each {|n| p n}
    

    This loop in Python breaks at 9:

    for j in range(0 , 10):
        print (j)