I have build the basic bubble sort algorithm with Ruby, without problems. The code is as follows:
def bubble_sort(arr)
swapped=true
while swapped
swapped=false
for j in 0..arr.length-2 do
if arr[j]>arr[j+1]
arr[j], arr[j+1] = arr[j+1], arr[j]
swapped=true
end
end
end
arr
end
Now, I am trying to implement the same method, but with a function of accepting code block. Code block part works fine, but when code block is not provided, the method should work like above, although it looks logically same to me, but for some reason, it goes into an infinite loop:
On the line of "unless", it will check for the condition and swap positions if necessary, and will skip the yield part. I tried step by step debugging by rdebugger but could not find out the reason.
def bubble_sort_by(arr)
swapped = true
while swapped
swapped=false
for i in 0..arr.length-2 do
unless block_given?
arr[i], arr[i+1] = arr[i+1], arr[i] if arr[i] < arr[i+1]
swapped=true
end #unless
if block_given?
if yield(arr[i], arr[i+1])>0
arr[i], arr[i+1] = arr[i+1], arr[i]
swapped=true
end #if yield
end #if block_given?
end #for
end #while
puts arr
return arr
end
Quick answer:
arr[i], arr[i+1] = arr[i+1], arr[i] if arr[i] < arr[i+1]
swapped=true
Should be replaced with:
if arr[i] < arr[i+1]
arr[i], arr[i+1] = arr[i+1], arr[i]
swapped=true
end
What's happening is you're always setting swapped
to true
, even if the elements were not swapped. So you get stuck in an infinite loop.
And now for a bit of code clean-up... First, rather than writing:
if(foo)
# ...
end
unless(foo)
# ...
end
Let's make it an if
/else
statement:
def bubble_sort_by(arr)
swapped = true
while swapped
swapped=false
for i in 0..arr.length-2 do
if block_given?
if yield(arr[i], arr[i+1])>0
arr[i], arr[i+1] = arr[i+1], arr[i]
swapped=true
end
else
if arr[i] < arr[i+1]
arr[i], arr[i+1] = arr[i+1], arr[i]
swapped=true
end
end
end #for
end #while
return arr
end
You could re-factor it further to remove the while
loop as @Aetherus suggests, but I figured you'd appreciate seeing the actual bug fixed.