-- $Id: heapsort.ghc,v 1.2 2001/05/08 02:46:59 doug Exp $ -- http://www.bagley.org/~doug/shootout/ -- from Julian Assange module Main(main) where import System(getArgs, exitWith, ExitCode(..)) import Numeric(showFFloat) main = do arg <- getArgs case arg of [num] -> putStrLn (showFFloat (Just 10) answer "") where answer = last . heapsort . take (read num) . random $ 1.0 _ -> exitWith (ExitFailure 1) -- construct an infinite list of random numbers random :: Double -> [Double] random max = map norm . rand $ 42 where norm x = (fromIntegral x) * (max / (fromIntegral im)) rand x = x' : (rand x') where x' = (x * ia + ic) `mod` im im = 139968 ia = 3877 ic = 29573 -- fold up a list like a tree treefold f z [] = z treefold f z [x] = x treefold f z (a:b:l) = treefold f z (f a b : pairfold l) where pairfold (x:y:rest) = f x y : pairfold rest pairfold l = l -- heapfold using linked lists data Heap a = Nil | Node a [Heap a] heapsort :: Ord a => [a] -> [a] heapsort = flatten_heap . merge_heaps . map heapify where heapify x = Node x [] merge_heaps :: Ord a => [Heap a] -> Heap a merge_heaps = treefold merge_heap Nil flatten_heap Nil = [] flatten_heap (Node x heaps) = x:flatten_heap (merge_heaps heaps) merge_heap Nil Nil = Nil merge_heap heap@(Node _ _) Nil = heap merge_heap node_a@(Node a heaps_a) node_b@(Node b heaps_b) | a < b = Node a (node_b : heaps_a) | otherwise = Node b (node_a : heaps_b)