Skip to content

Instantly share code, notes, and snippets.

@cvanweelden
Created March 25, 2012 15:46
Show Gist options
  • Save cvanweelden/2197630 to your computer and use it in GitHub Desktop.
Save cvanweelden/2197630 to your computer and use it in GitHub Desktop.
inversions :: (Ord a) => [a] -> Int
inversions list = let (n,_) = inversions' list in n
inversions' :: (Ord a) => [a] -> (Int,[a])
inversions' [] = (0, [])
inversions' [a] = (0, [a])
inversions' list =
let half = (length list) `div` 2
(na, a) = inversions' (take half list)
(nb, b) = inversions' (drop half list)
(nc, c) = mergeCount a b
in (na+nb+nc, c)
mergeCount :: (Ord a) => [a] -> [a] -> (Int,[a])
mergeCount [] b = (0,b)
mergeCount a [] = (0,a)
mergeCount (a:as) (b:bs)
| a <= b = let (nc,c) = mergeCount as (b:bs) in (nc, a:c)
| b < a = let (nc,c) = mergeCount (a:as) bs in (nc + length (a:as), b:c)
main = do string <- readFile "IntegerArray.txt"
let strings = words string
let numbers = map read strings :: [Int]
let result = inversions numbers
print result
module Main (
main
) where
inversions :: (Ord a) => [a] -> Int
inversions = fst . inversions'
where
inversions' list
| half < 1 = (0, list)
| otherwise = (na + nb + nc, cs')
where
half = length list `div` 2
(as, bs) = splitAt half list
(na, as') = inversions' as
(nb, bs') = inversions' bs
(nc, cs') = mergeCount as' bs'
mergeCount [] ys = (0, ys)
mergeCount xs [] = (0, xs)
mergeCount xs@(a:as) ys@(b:bs)
| a <= b = case mergeCount as ys of (nc, c) -> (nc, a:c)
| otherwise = case mergeCount xs bs of (nc, c) -> (nc + length xs, b:c)
main :: IO ()
main = do
numbers <- readInts "IntegerArray.txt"
print $ inversions numbers
where
readInts :: String -> IO [Int]
readInts fileName = do
string <- readFile fileName
return [read w | w <- words string]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment