Module: LilUtils::Misc::BinarySearch
- Defined in:
- lib/lilutils/misc/binary_search.rb
Class Method Summary collapse
- .in_order?(array, &block) ⇒ Boolean
- .sandwiching_indexes_for(value, array, fi = 0, li = array.length-1, check_if_in_order = true) ⇒ Object
Class Method Details
.in_order?(array, &block) ⇒ Boolean
22 23 24 25 26 27 28 29 30 31 |
# File 'lib/lilutils/misc/binary_search.rb', line 22 def self.in_order?(array, &block) block = Proc.new {|x, y| x <=> y} unless block_given? old_order = new_order = 0 array.each_cons(2) do |a| new_order = block.call(a[0], a[1]) return false if (new_order > 0 and old_order < 0) or (new_order < 0 and old_order > 0) old_order = new_order if new_order != 0 end true end |
.sandwiching_indexes_for(value, array, fi = 0, li = array.length-1, check_if_in_order = true) ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# File 'lib/lilutils/misc/binary_search.rb', line 5 def self.sandwiching_indexes_for(value, array, fi=0, li=array.length-1, check_if_in_order=true) # it is __not__ assumed that the array is sorted, we skip the check if we are asked to if check_if_in_order raise ArgumentError, "Unordered array provided to this routine based on binary search" unless in_order? array end # make other checks while true i = fi + (li-fi+1)/2 # Google "nearly all binary searches are broken" return [i, i] if array[i] == value return [fi, li] if (fi+1) >= li and value >= array[fi] and value <=array[li] return [fi-1, fi] if (fi+1) >= li and value <= array[fi] return [li, li+1] if (fi+1) >= li and value >= array[fi] value < array[i] ? li = i : fi = i #puts "fi=#{fi}, li=#{li}" end end |