```-- \$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

main = do input <- getContents
putAns (lines input)

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

-- 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)
```