-- $Id: moments.ghc,v 1.1 2001/02/14 22:12:21 doug Exp $ -- http://www.bagley.org/~doug/shootout/ -- from Brian Gregor module Main where import IO import System import Numeric -- read the file main = do input <- getContents putAns (lines input) -- print out the answers putAns :: [String] -> IO () putAns st_nums = do putStrLn ("n: " ++ (showInt (truncate n) "")) putStrLn ("median: " ++ (showFFloat (Just 6) (median nums n) "")) putStrLn ("mean: " ++ (showFFloat (Just 6) mean "")) putStrLn ("average_deviation: " ++ (showFFloat (Just 6) avg_dev "")) putStrLn ("standard_deviation: " ++ (showFFloat (Just 6) std_dev "")) putStrLn ("variance: " ++ (showFFloat (Just 6) var "")) putStrLn ("skew: " ++ (showFFloat (Just 6) skew "")) putStrLn ("kurtosis: " ++ (showFFloat (Just 6) kurt "")) where n = fromIntegral (length nums) nums = strToDoub st_nums mean = (sum nums) / n deviation = [x-mean | x <- nums] avg_dev = (sum [abs x | x <- deviation])/ n var = (sum [x**2 | x <- deviation]) / (n-1) std_dev = sqrt var skew = (sum [x**3 | x <- deviation]) / (n*var*std_dev) kurt = (sum [x**4 | x <- deviation]) / (n*var*var)-3.0 -- convert the strings to doubles strToDoub :: [String] -> [Double] strToDoub nums = map conv nums where conv x = fst (head (readFloat x)) -- calculate the median median :: [Double] -> Double -> Double median nums n = mid (mSort nums) where mid x | odd (length x) = x!! midpt | otherwise = ((x!!(midpt-1)) + (x!!midpt)) / 2.0 midpt :: Int midpt = floor (n/2) -- Sorting: the various languages use various algorithms -- here's an optimized mergesort from -- "Algorithms - a Functional Approach" by -- Fethi Rabhe & Guy Lapalme split :: (Ord a) => [a] -> [[a]] split [] = [] split (x:xs) = [x]:split xs merge :: (Ord a) => [a] -> [a] -> [a] merge [] b = b merge a [] = a merge a@(x:xs) b@(y:ys) | (x<=y) = x : (merge xs b) | otherwise = y : (merge a ys) mergepairs :: (Ord a) => [[a]] -> [[a]] mergepairs [] = [] mergepairs x@[l] = x mergepairs (l1:l2:rest) = (merge l1 l2) : (mergepairs $! rest) -- The actual sort mSort :: (Ord a) => [a] -> [a] mSort l = ms (split l) where ms [r] = r ms l = ms (mergepairs l)