Skip to content
Browse files

Added binary search algorithms previously found in LastOfTheCarelessM…

…en's Vector repo, updating their tests to current Rakudo.
  • Loading branch information...
1 parent 4878de0 commit babe643bd37fe191959da4c044fe065037114fed @colomon committed Sep 14, 2010
Showing with 70 additions and 0 deletions.
  1. +1 −0 CREDITS
  2. +40 −0 lib/List/Utils.pm
  3. +29 −0 t/05-search.t
View
1 CREDITS
@@ -1,3 +1,4 @@
Solomon Foster (colomon)
Nuno Carvalho (smashz/smash)
Moritz Lenz
+SF (LastOfTheCarelessMen @ github)
View
40 lib/List/Utils.pm
@@ -62,3 +62,43 @@ sub transpose(@list is copy) is export(:DEFAULT) {
}
}
+sub lower-bound(@x, $key) is export(:DEFAULT) {
+ my $first = 0;
+ my $len = @x.elems;
+ my $half;
+ while ($len > 0 && $first < @x.elems)
+ {
+ $half = $len div 2;
+ if (@x[$first + $half] < $key)
+ {
+ $first += $half + 1;
+ $len -= $half + 1;
+ }
+ else
+ {
+ $len = $half;
+ }
+ }
+ return $first;
+}
+
+sub upper-bound(@x, $key) is export(:DEFAULT) {
+ my $first = 0;
+ my $len = @x.elems;
+ my $half;
+ while ($len > 0 && $first < @x.elems)
+ {
+ $half = $len div 2;
+ if (@x[$first + $half] <= $key)
+ {
+ $first += $half + 1;
+ $len -= $half + 1;
+ }
+ else
+ {
+ $len = $half;
+ }
+ }
+ return $first;
+}
+
View
29 t/05-search.t
@@ -0,0 +1,29 @@
+use v6;
+use Test;
+use List::Utils;
+
+plan *;
+
+my @array = (1, 2, 2, 3, 4, 5, 5, 5, 5, 6, 7, 8);
+
+ok(([<=] @array), "array is sorted properly");
+
+for (1.5, 2, 2.5, 3, 3.5, 4, 5.5, 6, 8) -> $x
+{
+ my $i = lower-bound(@array, $x);
+ ok(@array[$i - 1] < $x <= @array[$i], "lower bound - 1 < $x <= lower bound");
+}
+
+is(lower-bound(@array, 8.5), @array.elems, "Off the big end returns max_index + 1");
+is(upper-bound(@array, 0.5), 0, "Off the little end returns 0");
+
+for (1.5, 2, 2.5, 3, 3.5, 4, 5.5, 6) -> $x
+{
+ my $i = upper-bound(@array, $x);
+ ok(@array[$i - 1] <= $x < @array[$i], "upper bound - 1 <= $x < upper bound");
+}
+
+is(lower-bound(@array, 8), @array.elems - 1, "Equal to the big end returns max_index");
+is(lower-bound(@array, 8.5), @array.elems, "Off the big end returns max_index + 1");
+
+done_testing;

0 comments on commit babe643

Please sign in to comment.
Something went wrong with that request. Please try again.