Commit 451574f1 authored by Christopher Aue's avatar Christopher Aue

Refactored Array#bsearch

parent 8a6ce74b
......@@ -596,30 +596,36 @@ class Array
return to_enum :bsearch unless block_given?
low = 0
high = self.size
high = size
satisfied = false
while low < high
mid = low + ((high - low) / 2).truncate
mid = ((low+high)/2).truncate
val = self[mid]
v = block.call(val)
if v.is_a?(Integer)
return val if v == 0
smaller = v < 0
elsif v == true
res = block.call val
case res
when 0 # find-any mode: Found!
return val
when Numeric # find-any mode: Continue...
in_lower_half = res < 0
when true # find-min mode
in_lower_half = true
satisfied = true
smaller = true
elsif v == false || v.nil?
smaller = false
when false, nil # find-min mode
in_lower_half = false
else
raise TypeError, 'invalid block result (must be numeric, true, false or nil)'
end
if smaller
if in_lower_half
high = mid
else
low = mid + 1
end
end
return nil if low == self.size
return nil unless satisfied
self[low]
satisfied ? self[low] : nil
end
##
......
......@@ -260,6 +260,11 @@ assert("Array#bsearch") do
assert_equal 4, a.bsearch{ |x| between( 0, x, 4) }
assert_equal 4, a.bsearch{ |x| between( 4, x, 8) }
assert_equal 8, a.bsearch{ |x| between( 5, x, 8) }
# Invalid block result
assert_raise TypeError, 'invalid block result (must be numeric, true, false or nil)' do
a.bsearch{ 'I like to watch the world burn' }
end
end
assert("Array#delete_if") do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment