Ответ 1
arr_in = [-1, 1,2,4,5]
arr_in.bsearch{ |x| 2 - x }
#=> 2
arr_in.bsearch{ |x| -1 - x }
#=> -1
arr_in.bsearch{ |x| 3 - x }
#=> nil
Двоичный поиск использует результат блока как подсказку, какая часть массива (левая или правая сторона) должна быть выбрана для поиска на следующей итерации. Если блок возвращает 0, он прекратит поиск. Если он возвращает меньше 0, он будет идти влево, иначе он будет прав:)
Подробнее здесь http://www.ruby-doc.org/core-2.1.1/Array.html#method-i-bsearch
UPD
Хорошо, возьмем ваш пример
arr_in = [-1, 1, 2, 4, 5]
arr_in.bsearch { |x| x == 3 }
Сначала мы возьмем средний элемент (2) и передадим его блоку. 2 == 3
вернет false
, поэтому мы перейдем к правой части массива.
Возьмем средний элемент [4, 5]
, который 5
и 5 == 3
равен false
Нет никаких элементов справа, поэтому мы вернем nil
arr_in = [-1, 1, 2, 4, 5]
arr_in.bsearch { |x| x == 2 }
Первый 2 == 2
- true
. Мы идем влево.
Средний элемент [-1, 1]
равен 1. 1 == 2
is false
. Мы идем направо.
В [-1, 1]
нет никаких элементов справа от 1, поэтому мы возвращаем последний последний элемент, который возвращает оператор true
, который равен 2
PS: не забывайте, что массив должен быть отсортирован;)