(* -*- mode: sml -*- * $Id: heapsort.smlnj,v 1.3 2001/07/09 00:25:28 doug Exp $ * http://www.bagley.org/~doug/shootout/ * Based on cdoe from Stephen Weeks, improved by Henry Cejtin. *) structure Test : sig val main : (string * string list) -> OS.Process.status end = struct val sub = Array.sub val update = Array.update local val im = 139968 val ia = 3877 val ic = 29573 val last = ref 42 val scale = 1.0 / Real.fromInt im in fun gen_random max = let val last' = (! last * ia + ic) mod im in last := last'; max * scale * Real.fromInt last' end end fun heapSort (n, ra: real array) = let fun inner (l, ir, rra) = let fun loop (i, j) = if j <= ir then let val j = if j < ir andalso sub (ra, j) < sub (ra, j + 1) then j + 1 else j val (i, j) = if rra < sub (ra, j) then (update (ra, i, sub (ra, j)); (j, j + j)) else (i, ir + 1) in loop (i, j) end else update (ra, i, rra) in loop (l, l + l) end fun outer1 l = let val l' = l - 1 in if l' > 0 then (inner (l', n, sub (ra, l')); outer1 l') else () end fun outer2 ir = let val rra = sub (ra, ir) val _ = update (ra, ir, sub (ra, 1)) val ir = ir - 1 in if ir = 1 then update (ra, 1, rra) else (inner (1, ir, rra); outer2 ir) end in outer1 (n div 2 + 1); outer2 n end fun atoi s = case Int.fromString s of SOME num => num | NONE => 0; fun printl [] = print "\n" | printl(h::t) = ( print h ; printl t ); fun main (name, args) = let val n = atoi (hd (args @ ["1"])) val ary = Array.tabulate (n + 1, fn _ => gen_random 1.0) in heapSort (n, ary); print (concat [Real.fmt (StringCvt.FIX (SOME 10)) (sub (ary, n)), "\n"]); OS.Process.success end end val _ = SMLofNJ.exportFn("heapsort", Test.main);