shithub: mc

Download patch

ref: 61766f9822581c7f7ed44c66ff975517b350987a
parent: df187615868a82da67b31b921334449f7db5a868
author: Ori Bernstein <[email protected]>
date: Thu May 8 10:09:48 EDT 2014

Add 'search' functions:

    bsearch: does a binary search on a sorted array
    lsearch: does a linear search on any array

--- a/libstd/Makefile
+++ b/libstd/Makefile
@@ -27,6 +27,7 @@
     optparse.myr \
     rand.myr \
     resolve.myr \
+    search.myr \
     slcp.myr \
     sldup.myr \
     sleq.myr \
--- /dev/null
+++ b/libstd/search.myr
@@ -1,0 +1,42 @@
+use "cmp.use"
+use "option.use"
+use "fmt.use"
+
+pkg std =
+	generic lsearch	: (sl : @t[:], val : @t, cmp : (a : @t, b : @t -> order) -> option(@idx::(integral,numeric)))
+	generic bsearch	: (sl : @t[:], val : @t, cmp : (a : @t, b : @t -> order) -> option(@idx::(integral,numeric)))
+;;
+
+/* linear search over a list of values */
+generic lsearch = {sl, val, cmp
+	var i
+
+	for i = 0; i < sl.len; i++
+		match cmp(sl[i], val)
+		| `Equal:
+			-> `Some i
+		;;
+	;;
+	-> `None
+}
+
+/* binary search over a sorted list of values. */
+generic bsearch  = {sl, val, cmp
+	var hi, lo, mid
+
+	lo = 0
+	hi = sl.len - 1
+
+	while lo <= hi
+		mid = (hi + lo) / 2
+		match cmp(val, sl[mid])
+		| `Before:	hi = mid - 1
+		| `After:	lo = mid + 1
+		| `Equal:	
+			-> `Some mid
+		;;
+	;;
+	-> `None
+}
+		
+
--- /dev/null
+++ b/test/stdsearch.myr
@@ -1,0 +1,33 @@
+use std
+
+const sl = [1, 3, 5, 8, 9, 33]
+
+const main = {
+
+	expect(std.lsearch(sl[:], 1, std.numcmp), `std.Some 0)
+	expect(std.lsearch(sl[:], 33, std.numcmp), `std.Some sl.len - 1)
+	expect(std.lsearch(sl[:], 5, std.numcmp), `std.Some 2)
+	expect(std.lsearch(sl[:], 6, std.numcmp), `std.None)
+
+	expect(std.bsearch(sl[:], 1, std.numcmp), `std.Some 0)
+	expect(std.bsearch(sl[:], 33, std.numcmp), `std.Some sl.len - 1)
+	expect(std.bsearch(sl[:], 5, std.numcmp), `std.Some 2)
+	expect(std.bsearch(sl[:], 6, std.numcmp), `std.None)
+}
+
+const expect = {a, b
+	match a
+	| `std.None:
+		match b
+		| `std.Some x: std.fatal(1, "Expected `std.None, `std.None, got `std.None, `std.Some %i\n", x)
+		;;
+	| `std.Some x:
+		match b
+		| `std.None: std.fatal(1, "Expected `std.Some %i, `std.Some %i, got `std.Some %i, `std.None\n", x, x, x)
+		| `std.Some y: 
+			if x != y
+				std.fatal(1, "Expected `std.Some %i, `std.Some %i, got `std.Some %i, `std.Some %i\n", x, x, x, y)
+			;;
+		;;
+	;;
+}
--- a/test/tests
+++ b/test/tests
@@ -115,6 +115,7 @@
 B strtab	C
 B catfile	C
 B stdsort	C
+B stdsearch	E	0
 B strstrip	C
 B strsplit	C
 B strfind	C