shithub: mc

Download patch

ref: 3abec38baad46bc1317fc8a8b9c1fdd38494aef4
parent: 64e3b36c8a1cc2c10248a4761e092234b8eccfe2
author: Ori Bernstein <[email protected]>
date: Mon Dec 30 18:04:29 EST 2013

Implement heapsort and add to libstd.

--- a/libstd/Makefile
+++ b/libstd/Makefile
@@ -25,6 +25,7 @@
     sljoin.myr \
     slpush.myr \
     slurp.myr \
+    sort.myr \
     strfind.myr \
     strjoin.myr \
     strsplit.myr \
--- /dev/null
+++ b/libstd/sort.myr
@@ -1,0 +1,63 @@
+pkg std =
+	type order = union
+		`Before
+		`Equal
+		`After
+	;;
+	generic sort	: (sl:@a[:], cmp:(a:@a, b:@a -> order) -> @a[:])
+;;
+
+generic sort = {sl, cmp
+	var end
+
+	heapify(sl, cmp)
+	end = sl.len - 1
+	while end > 0
+		swap(sl, end, 0)
+		end--
+		siftdown(sl[:end], 0, cmp)
+	;;
+	-> sl
+}
+
+generic heapify = {sl, cmp
+	var start
+
+	start = sl.len/2 - 1
+	while start >= 0
+		siftdown(sl, start, cmp)
+		start--
+	;;
+}
+
+generic siftdown = {sl, start, cmp
+	var r, c, s
+
+	r = start
+	while 2*r + 1 <= sl.len
+		c = r*2 + 1
+		s = r
+		match cmp(sl[s], sl[c])
+		| `Before:	s = c
+		;;
+		if c + 1 < sl.len
+			match cmp(sl[s], sl[c + 1])
+			| `Before:	s = c + 1
+			;;
+		;;
+		if s != r
+			swap(sl, r, s)
+			r = s
+		else
+			->
+		;;
+	;;
+}
+
+generic swap = {sl, i, j
+	var tmp
+	tmp = sl[i]
+	sl[i] = sl[j]
+	sl[j] = tmp
+}
+
--- /dev/null
+++ b/test/data/stdsort-expected
@@ -1,0 +1,10 @@
+0
+2
+1
+3
+4
+5
+6
+7
+8
+9
--- /dev/null
+++ b/test/stdsort.myr
@@ -1,0 +1,24 @@
+use std
+
+const main = {
+	var a = [
+		3, 5, 4, 9, 7, 2, 6, 0, 1, 8,
+	]
+
+	std.sort(a[:], intcmp)
+	for i in a
+		std.put("%i\n", i)
+	;;
+}
+
+const intcmp = {a, b
+	if a < b
+		-> `std.Before
+	elif a == b
+		-> `std.Equal
+	else
+		-> `std.After
+	;;
+}
+
+	
--- a/test/tests
+++ b/test/tests
@@ -108,6 +108,7 @@
 B encodechar	P	1世界äa
 B strtab	C
 B catfile	C
+B stdsort	C
 B strstrip	C
 B strsplit	C
 B strfind	C