Search code examples
rubybsearch

reversed expression in bsearch block not working


ary = [1, 4, 6, 9]
(0...ary.size).bsearch { |i|
  ary[i] - 1
}                                   # => nil

1 - ary[i]                          # => 0

When the code is written in a form ary[i] - 1 which doesn't work as expected.

What I am trying to do is to find the index of the number 1 in the array.

But 1 - ary[i] can return the number's index correctly. Why doesn't ary[i] - 1 work?


Solution

  • Array#bsearch is meant to perform binary search to find an element that meets certain criteria. As per documentation, if you return numeric values from the block, the find-any mode type of search is used.

    The search starts at center of the sorted array - and if block returns negative value, it continues search in first half, and if block returns positive value, it continues the search in second half of the array.

    In your case when you use ary[i] - 1, the value returned by block is always positive and search continues recursively on second half of the array - and never finds the value 1.

    Here is the code with some debug statements:

    ary = [1, 4, 6, 9]
    p (0...ary.size).bsearch { |i|
      puts "Elem: #{ary[i]} Index: #{i}"
      ary[i] - 1
    }
    

    Output:

    Elem: 4 Index: 1
    Elem: 6 Index: 2
    Elem: 9 Index: 3
    nil
    [Finished in 0.4s]