Files
lean4/tests/bench/qsort.sml
2019-05-29 16:33:50 +02:00

81 lines
1.8 KiB
Standard ML

open Array
type elem = Word32.word
fun badRand (seed : elem) : elem = (seed * Word32.fromInt 1664525) + Word32.fromInt 1013904223
fun mkRandomArray (seed : elem) n =
let val s = ref seed in
tabulate (n, fn _ =>
let val seed = (!s) in
s := badRand seed;
seed
end)
end
exception Unsorted of string
fun checkSortedAux (a : elem array) i =
if i < Array.length a - 1 then (
if sub (a, i) > sub (a, i+1) then raise (Unsorted "array is not sorted") else ();
checkSortedAux a (i+1)
) else ()
fun swap (arr : elem array) i j =
let
val x = sub (arr, i)
val y = sub (arr, j) in
(update (arr, i, y); update (arr, j, x))
end
fun partitionAux hi pivot arr i j : int =
if j < hi then (
if sub (arr, j) < pivot then (
swap arr i j;
partitionAux hi pivot arr (i+1) (j+1)
) else
partitionAux hi pivot arr i (j+1)
) else (
swap arr i hi;
i
)
fun partition arr lo hi =
let val mid = (lo + hi) div 2 in (
if sub (arr, mid) < sub (arr, lo) then swap arr lo mid else ();
if sub (arr, hi) < sub (arr, lo) then swap arr lo hi else ();
if sub (arr, mid) < sub (arr, hi) then swap arr mid hi else ();
let val pivot = sub (arr, hi) in
partitionAux hi pivot arr lo lo
end)
end
fun qsortAux arr low high =
if low < high then
let val mid = partition arr low high in
(qsortAux arr low mid;
qsortAux arr (mid+1) high)
end
else ()
fun qsort arr =
qsortAux arr 0 (Array.length arr - 1)
fun for (start, stop, f) =
let
fun loop i = if i = stop then () else (f i; loop (i + 1))
in
loop start
end
fun main n =
for (0, n-1, fn _ =>
for (0, n-1, fn i =>
let val xs = mkRandomArray (Word32.fromInt i) i in
(qsort xs;
checkSortedAux xs 0)
end
)
)
val _ = main ((valOf o Int.fromString o List.hd o CommandLine.arguments) ())