[前][次][番号順一覧][スレッド一覧]

ruby-changes:67986

From: Burdette <ko1@a...>
Date: Wed, 15 Sep 2021 06:08:39 +0900 (JST)
Subject: [ruby-changes:67986] 1af5a0c574 (master): Bsearch doc for Array and Range (#4838)

https://git.ruby-lang.org/ruby.git/commit/?id=1af5a0c574

From 1af5a0c574e45dae22098af855c124e12fb8bb6d Mon Sep 17 00:00:00 2001
From: Burdette Lamar <BurdetteLamar@Y...>
Date: Tue, 14 Sep 2021 16:08:21 -0500
Subject: Bsearch doc for Array and Range (#4838)

This PR creates doc/bsearch.rdoc to provide common documentation for bsearch in Array and Range.
---
 array.c          |  83 +-------------------------------------
 doc/bsearch.rdoc | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 range.c          |  46 +--------------------
 3 files changed, 123 insertions(+), 126 deletions(-)
 create mode 100644 doc/bsearch.rdoc

diff --git a/array.c b/array.c
index 20ed970..d3eb7ce 100644
--- a/array.c
+++ b/array.c
@@ -3422,89 +3422,8 @@ static VALUE rb_ary_bsearch_index(VALUE ary); https://github.com/ruby/ruby/blob/trunk/array.c#L3422
  *    array.bsearch -> new_enumerator
  *
  *  Returns an element from +self+ selected by a binary search.
- *  +self+ should be sorted, but this is not checked.
  *
- *  By using binary search, finds a value from this array which meets
- *  the given condition in <tt>O(log n)</tt> where +n+ is the size of the array.
- *
- *  There are two search modes:
- *  - <b>Find-minimum mode</b>: the block should return +true+ or +false+.
- *  - <b>Find-any mode</b>: the block should return a numeric value.
- *
- *  The block should not mix the modes by and sometimes returning +true+ or +false+
- *  and sometimes returning a numeric value, but this is not checked.
- *
- *  <b>Find-Minimum Mode</b>
- *
- *  In find-minimum mode, the block always returns +true+ or +false+.
- *  The further requirement (though not checked) is that
- *  there are no indexes +i+ and +j+ such that:
- *  - <tt>0 <= i < j <= self.size</tt>.
- *  - The block returns +true+ for <tt>self[i]</tt> and +false+ for <tt>self[j]</tt>.
- *
- *  In find-minimum mode, method bsearch returns the first element for which the block returns true.
- *
- *  Examples:
- *    a = [0, 4, 7, 10, 12]
- *    a.bsearch {|x| x >= 4 } # => 4
- *    a.bsearch {|x| x >= 6 } # => 7
- *    a.bsearch {|x| x >= -1 } # => 0
- *    a.bsearch {|x| x >= 100 } # => nil
- *
- *  Less formally: the block is such that all +false+-evaluating elements
- *  precede all +true+-evaluating elements.
- *
- *  These make sense as blocks in find-minimum mode:
- *    a = [0, 4, 7, 10, 12]
- *    a.map {|x| x >= 4 } # => [false, true, true, true, true]
- *    a.map {|x| x >= 6 } # => [false, false, true, true, true]
- *    a.map {|x| x >= -1 } # => [true, true, true, true, true]
- *    a.map {|x| x >= 100 } # => [false, false, false, false, false]
- *
- *  This would not make sense:
- *    a = [0, 4, 7, 10, 12]
- *    a.map {|x| x == 7 } # => [false, false, true, false, false]
- *
- *  <b>Find-Any Mode</b>
- *
- *  In find-any mode, the block always returns a numeric value.
- *  The further requirement (though not checked) is that
- *  there are no indexes +i+ and +j+ such that:
- *  - <tt>0 <= i < j <= self.size</tt>.
- *  - The block returns a negative value for <tt>self[i]</tt>
- *    and a positive value for <tt>self[j]</tt>.
- *  - The block returns a negative value for <tt>self[i]</tt> and zero <tt>self[j]</tt>.
- *  - The block returns zero for <tt>self[i]</tt> and a positive value for <tt>self[j]</tt>.
- *
- *  In find-any mode, method bsearch returns some element
- *  for which the block returns zero, or +nil+ if no such element is found.
- *
- *  Examples:
- *    a = [0, 4, 7, 10, 12]
- *    a.bsearch {|element| 7 <=> element } # => 7
- *    a.bsearch {|element| -1 <=> element } # => nil
- *    a.bsearch {|element| 5 <=> element } # => nil
- *    a.bsearch {|element| 15 <=> element } # => nil
- *
- *  Less formally: the block is such that:
- *  - All positive-evaluating elements precede all zero-evaluating elements.
- *  - All positive-evaluating elements precede all negative-evaluating elements.
- *  - All zero-evaluating elements precede all negative-evaluating elements.
- *
- *  These make sense as blocks in find-any mode:
- *    a = [0, 4, 7, 10, 12]
- *    a.map {|element| 7 <=> element } # => [1, 1, 0, -1, -1]
- *    a.map {|element| -1 <=> element } # => [-1, -1, -1, -1, -1]
- *    a.map {|element| 5 <=> element } # => [1, 1, -1, -1, -1]
- *    a.map {|element| 15 <=> element } # => [1, 1, 1, 1, 1]
- *
- *  This would not make sense:
- *    a = [0, 4, 7, 10, 12]
- *    a.map {|element| element <=> 7 } # => [-1, -1, 0, 1, 1]
- *
- *  Returns an enumerator if no block given:
- *    a = [0, 4, 7, 10, 12]
- *    a.bsearch # => #<Enumerator: [0, 4, 7, 10, 12]:bsearch>
+ *  See {Binary Searching}[doc/bsearch_rdoc.html].
  */
 
 static VALUE
diff --git a/doc/bsearch.rdoc b/doc/bsearch.rdoc
new file mode 100644
index 0000000..ca8091f
--- /dev/null
+++ b/doc/bsearch.rdoc
@@ -0,0 +1,120 @@ https://github.com/ruby/ruby/blob/trunk/doc/bsearch.rdoc#L1
+== Binary Searching
+
+A few Ruby methods support binary searching in a collection:
+
+Array#bsearch:: Returns an element selected via a binary search
+                as determined by a given block.
+Array#bsearch_index:: Returns the index of an element selected via a binary search
+                      as determined by a given block.
+Range#bsearch:: Returns an element selected via a binary search
+                as determined by a given block.
+
+Each of these methods returns an enumerator if no block is given.
+
+Given a block, each of these methods returns an element (or element index) from +self+
+as determined by a binary search.
+The search finds an element of +self+ which meets
+the given condition in <tt>O(log n)</tt> operations, where +n+ is the count of elements.
++self+ should be sorted, but this is not checked.
+
+There are two search modes:
+
+Find-minimum mode:: method +bsearch+ returns the first element for which
+                    the block returns +true+;
+                    the block must return +true+ or +false+.
+Find-any mode:: method +bsearch+ some element, if any, for which
+                the block returns zero.
+                the block must return a numeric value.
+
+The block should not mix the modes by sometimes returning +true+ or +false+
+and other times returning a numeric value, but this is not checked.
+
+<b>Find-Minimum Mode</b>
+
+In find-minimum mode, the block must return +true+ or +false+.
+The further requirement (though not checked) is that
+there are no indexes +i+ and +j+ such that:
+
+- <tt>0 <= i < j <= self.size</tt>.
+- The block returns +true+ for <tt>self[i]</tt> and +false+ for <tt>self[j]</tt>.
+
+Less formally: the block is such that all +false+-evaluating elements
+precede all +true+-evaluating elements.
+
+In find-minimum mode, method +bsearch+ returns the first element
+for which the block returns +true+.
+
+Examples:
+
+  a = [0, 4, 7, 10, 12]
+  a.bsearch {|x| x >= 4 } # => 4
+  a.bsearch {|x| x >= 6 } # => 7
+  a.bsearch {|x| x >= -1 } # => 0
+  a.bsearch {|x| x >= 100 } # => nil
+
+  r = (0...a.size)
+  r.bsearch {|i| a[i] >= 4 } #=> 1
+  r.bsearch {|i| a[i] >= 6 } #=> 2
+  r.bsearch {|i| a[i] >= 8 } #=> 3
+  r.bsearch {|i| a[i] >= 100 } #=> nil
+  r = (0.0...Float::INFINITY)
+  r.bsearch {|x| Math.log(x) >= 0 } #=> 1.0
+
+These blocks make sense in find-minimum mode:
+
+  a = [0, 4, 7, 10, 12]
+  a.map {|x| x >= 4 } # => [false, true, true, true, true]
+  a.map {|x| x >= 6 } # => [false, false, true, true, true]
+  a.map {|x| x >= -1 } # => [true, true, true, true, true]
+  a.map {|x| x >= 100 } # => [false, false, false, false, false]
+
+This would not make sense:
+
+  a.map {|x| x == 7 } # => [false, false, true, false, false]
+
+<b>Find-Any Mode</b>
+
+In find-any mode, the block must return a numeric value.
+The further requirement (though not checked) is that
+there are no indexes +i+ and +j+ such that:
+
+- <tt>0 <= i < j <= self.size</tt>.
+- The block returns a negative value for <tt>self[i]</tt>
+  and a positive value for <tt>self[j]</tt>.
+- The block returns a negative value for <tt>self[i]</tt> and zero <tt>self[j]</tt>.
+- The block returns zero for <tt>self[i]</tt> and a positive value for <tt>self[j]</tt>.
+
+Less formally: the block is such that:
+
+- All positive-evaluating elements precede all zero-evaluating elements.
+- All positive-evaluating elements precede all negative-evaluating elements.
+- All zero-evaluating elements precede all negative-evaluating elements.
+
+In find-any mode, method +bsearch+ returns some element
+for which the block returns zero, or +nil+ if no such element is found.
+
+Examples:
+
+  a = [0, 4, 7, 10, 12]
+  a.bsearch {|element| 7 <=> element } # => 7
+  a.bsearch {|element| -1 <=> element } # => nil
+  a.bsearch {|element| 5 <=> element } # => nil
+  a.bsearch {|element| 15 <=> element } # => nil
+
+  a = [0, 100, 100, 100, 200]
+  r = (0..4)
+  r.bsearch {|i| 100 - a[i] } #=> 1, 2 or 3
+  r.bsearch {|i| 300 - a[i] } #=> nil
+  r.bsearch {|i|  50 - a[i] } #=> nil
+
+These blocks make sense in find-any mode:
+
+  a = [0, 4, 7, 10, 12]
+  a.map {|element| 7 <=> element } # => [1, 1, 0, -1, -1]
+  a.map {|element| -1 <=> element } # => [-1, -1, -1, -1, -1]
+  a.map {|element| 5 <=> element } # => [1, 1, -1, -1, -1]
+  a.map {|element| 15 <=> element } # => [1, 1, 1, 1, 1]
+
+This would not make sense:
+
+  a.map {|element| element <=> 7 } # => [-1, -1, 0, 1, 1]
diff --git a/range.c b/range.c
index 140abc3..9dd2d4e 100644
--- a/range.c
+++ b/range.c
@@ -662,52 +662,10 @@ bsearch_integer_range(VALUE beg, VALUE end, int excl) https://github.com/ruby/ruby/blob/trunk/range.c#L662
  *  call-seq:
  *     rng.bsearch {|obj| block }  -> value
  *
- *  By using binary search, finds a value in range which meets the given
- *  condition in O(log n) where n is the size of the range.
+ *  Returns an element from +self+ selected by a binary search.
  *
- *  You can use this method in two use cases: a find-minimum mode and
- *  a find-any mode.  In either case, the elements of the range must be
- *  monotone (or sorted) with respect to the block.
+ *  See {Bin (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]