package scala.util
import scala.reflect.ClassManifest
import scala.math.Ordering
object Sorting {
def quickSort(a: Array[Double]) { sort1(a, 0, a.length) }
def quickSort[K: Ordering](a: Array[K]) { sort1(a, 0, a.length) }
def quickSort(a: Array[Int]) { sort1(a, 0, a.length) }
def quickSort(a: Array[Float]) { sort1(a, 0, a.length) }
def stableSort[K: ClassManifest: Ordering](a: Array[K]) {
stableSort(a, 0, a.length-1, new Array[K](a.length), Ordering[K].lt _)
}
def stableSort[K: ClassManifest](a: Array[K], f: (K, K) => Boolean) {
stableSort(a, 0, a.length-1, new Array[K](a.length), f)
}
def stableSort[K: ClassManifest](a: Seq[K], f: (K, K) => Boolean): Array[K] = {
val ret = a.toArray
stableSort(ret, f)
ret
}
def stableSort[K: ClassManifest: Ordering](a: Seq[K]): Array[K] =
stableSort(a, Ordering[K].lt _)
def stableSort[K: ClassManifest, M: Ordering](a: Seq[K], f: K => M): Array[K] =
stableSort(a)(implicitly[ClassManifest[K]], Ordering[M] on f)
private def sort1[K: Ordering](x: Array[K], off: Int, len: Int) {
val ord = Ordering[K]
import ord._
def swap(a: Int, b: Int) {
val t = x(a)
x(a) = x(b)
x(b) = t
}
def vecswap(_a: Int, _b: Int, n: Int) {
var a = _a
var b = _b
var i = 0
while (i < n) {
swap(a, b)
i += 1
a += 1
b += 1
}
}
def med3(a: Int, b: Int, c: Int) = {
if (x(a) < x(b)) {
if (x(b) < x(c)) b else if (x(a) < x(c)) c else a
} else {
if (x(b) > x(c)) b else if (x(a) > x(c)) c else a
}
}
def sort2(off: Int, len: Int) {
if (len < 7) {
var i = off
while (i < len + off) {
var j = i
while (j > off && x(j-1) > x(j)) {
swap(j, j-1)
j -= 1
}
i += 1
}
} else {
var m = off + (len >> 1)
if (len > 7) {
var l = off
var n = off + len - 1
if (len > 40) {
var s = len / 8
l = med3(l, l+s, l+2*s)
m = med3(m-s, m, m+s)
n = med3(n-2*s, n-s, n)
}
m = med3(l, m, n)
}
val v = x(m)
var a = off
var b = a
var c = off + len - 1
var d = c
var done = false
while (!done) {
while (b <= c && x(b) <= v) {
if (x(b) == v) {
swap(a, b)
a += 1
}
b += 1
}
while (c >= b && x(c) >= v) {
if (x(c) == v) {
swap(c, d)
d -= 1
}
c -= 1
}
if (b > c) {
done = true
} else {
swap(b, c)
c -= 1
b += 1
}
}
val n = off + len
var s = math.min(a-off, b-a)
vecswap(off, b-s, s)
s = math.min(d-c, n-d-1)
vecswap(b, n-s, s)
s = b - a
if (s > 1)
sort2(off, s)
s = d - c
if (s > 1)
sort2(n-s, s)
}
}
sort2(off, len)
}
private def sort1(x: Array[Int], off: Int, len: Int) {
def swap(a: Int, b: Int) {
val t = x(a)
x(a) = x(b)
x(b) = t
}
def vecswap(_a: Int, _b: Int, n: Int) {
var a = _a
var b = _b
var i = 0
while (i < n) {
swap(a, b)
i += 1
a += 1
b += 1
}
}
def med3(a: Int, b: Int, c: Int) = {
if (x(a) < x(b)) {
if (x(b) < x(c)) b else if (x(a) < x(c)) c else a
} else {
if (x(b) > x(c)) b else if (x(a) > x(c)) c else a
}
}
def sort2(off: Int, len: Int) {
if (len < 7) {
var i = off
while (i < len + off) {
var j = i
while (j>off && x(j-1) > x(j)) {
swap(j, j-1)
j -= 1
}
i += 1
}
} else {
var m = off + (len >> 1)
if (len > 7) {
var l = off
var n = off + len - 1
if (len > 40) {
var s = len / 8
l = med3(l, l+s, l+2*s)
m = med3(m-s, m, m+s)
n = med3(n-2*s, n-s, n)
}
m = med3(l, m, n)
}
val v = x(m)
var a = off
var b = a
var c = off + len - 1
var d = c
var done = false
while (!done) {
while (b <= c && x(b) <= v) {
if (x(b) == v) {
swap(a, b)
a += 1
}
b += 1
}
while (c >= b && x(c) >= v) {
if (x(c) == v) {
swap(c, d)
d -= 1
}
c -= 1
}
if (b > c) {
done = true
} else {
swap(b, c)
c -= 1
b += 1
}
}
val n = off + len
var s = math.min(a-off, b-a)
vecswap(off, b-s, s)
s = math.min(d-c, n-d-1)
vecswap(b, n-s, s)
s = b - a
if (s > 1)
sort2(off, s)
s = d - c
if (s > 1)
sort2(n-s, s)
}
}
sort2(off, len)
}
private def sort1(x: Array[Double], off: Int, len: Int) {
def swap(a: Int, b: Int) {
val t = x(a)
x(a) = x(b)
x(b) = t
}
def vecswap(_a: Int, _b: Int, n: Int) {
var a = _a
var b = _b
var i = 0
while (i < n) {
swap(a, b)
i += 1
a += 1
b += 1
}
}
def med3(a: Int, b: Int, c: Int) = {
val ab = x(a) compare x(b)
val bc = x(b) compare x(c)
val ac = x(a) compare x(c)
if (ab < 0) {
if (bc < 0) b else if (ac < 0) c else a
} else {
if (bc > 0) b else if (ac > 0) c else a
}
}
def sort2(off: Int, len: Int) {
if (len < 7) {
var i = off
while (i < len + off) {
var j = i
while (j > off && (x(j-1) compare x(j)) > 0) {
swap(j, j-1)
j -= 1
}
i += 1
}
} else {
var m = off + (len >> 1)
if (len > 7) {
var l = off
var n = off + len - 1
if (len > 40) {
var s = len / 8
l = med3(l, l+s, l+2*s)
m = med3(m-s, m, m+s)
n = med3(n-2*s, n-s, n)
}
m = med3(l, m, n)
}
val v = x(m)
var a = off
var b = a
var c = off + len - 1
var d = c
var done = false
while (!done) {
var bv = x(b) compare v
while (b <= c && bv <= 0) {
if (bv == 0) {
swap(a, b)
a += 1
}
b += 1
if (b <= c) bv = x(b) compare v
}
var cv = x(c) compare v
while (c >= b && cv >= 0) {
if (cv == 0) {
swap(c, d)
d -= 1
}
c -= 1
if (c >= b) cv = x(c) compare v
}
if (b > c) {
done = true
} else {
swap(b, c)
c -= 1
b += 1
}
}
val n = off + len
var s = math.min(a-off, b-a)
vecswap(off, b-s, s)
s = math.min(d-c, n-d-1)
vecswap(b, n-s, s)
s = b - a
if (s > 1)
sort2(off, s)
s = d - c
if (s > 1)
sort2(n-s, s)
}
}
sort2(off, len)
}
private def sort1(x: Array[Float], off: Int, len: Int) {
def swap(a: Int, b: Int) {
val t = x(a)
x(a) = x(b)
x(b) = t
}
def vecswap(_a: Int, _b: Int, n: Int) {
var a = _a
var b = _b
var i = 0
while (i < n) {
swap(a, b)
i += 1
a += 1
b += 1
}
}
def med3(a: Int, b: Int, c: Int) = {
val ab = x(a) compare x(b)
val bc = x(b) compare x(c)
val ac = x(a) compare x(c)
if (ab < 0) {
if (bc < 0) b else if (ac < 0) c else a
} else {
if (bc > 0) b else if (ac > 0) c else a
}
}
def sort2(off: Int, len: Int) {
if (len < 7) {
var i = off
while (i < len + off) {
var j = i
while (j > off && (x(j-1) compare x(j)) > 0) {
swap(j, j-1)
j -= 1
}
i += 1
}
} else {
var m = off + (len >> 1)
if (len > 7) {
var l = off
var n = off + len - 1
if (len > 40) {
var s = len / 8
l = med3(l, l+s, l+2*s)
m = med3(m-s, m, m+s)
n = med3(n-2*s, n-s, n)
}
m = med3(l, m, n)
}
val v = x(m)
var a = off
var b = a
var c = off + len - 1
var d = c
var done = false
while (!done) {
var bv = x(b) compare v
while (b <= c && bv <= 0) {
if (bv == 0) {
swap(a, b)
a += 1
}
b += 1
if (b <= c) bv = x(b) compare v
}
var cv = x(c) compare v
while (c >= b && cv >= 0) {
if (cv == 0) {
swap(c, d)
d -= 1
}
c -= 1
if (c >= b) cv = x(c) compare v
}
if (b > c) {
done = true
} else {
swap(b, c)
c -= 1
b += 1
}
}
val n = off + len
var s = math.min(a-off, b-a)
vecswap(off, b-s, s)
s = math.min(d-c, n-d-1)
vecswap(b, n-s, s)
s = b - a
if (s > 1)
sort2(off, s)
s = d - c
if (s > 1)
sort2(n-s, s)
}
}
sort2(off, len)
}
private def stableSort[K : ClassManifest](a: Array[K], lo: Int, hi: Int, scratch: Array[K], f: (K,K) => Boolean) {
if (lo < hi) {
val mid = (lo+hi) / 2
stableSort(a, lo, mid, scratch, f)
stableSort(a, mid+1, hi, scratch, f)
var k, t_lo = lo
var t_hi = mid + 1
while (k <= hi) {
if ((t_lo <= mid) && ((t_hi > hi) || (!f(a(t_hi), a(t_lo))))) {
scratch(k) = a(t_lo)
t_lo += 1
} else {
scratch(k) = a(t_hi)
t_hi += 1
}
k += 1
}
k = lo
while (k <= hi) {
a(k) = scratch(k)
k += 1
}
}
}
}