Skip to content

Instantly share code, notes, and snippets.

@weaming
Last active April 17, 2017 15:53
Show Gist options
  • Save weaming/a3bc144312f9de0e49a075f757c647a7 to your computer and use it in GitHub Desktop.
Save weaming/a3bc144312f9de0e49a075f757c647a7 to your computer and use it in GitHub Desktop.
Count the words of input text with beautiful output.
import qualified Data.Char as C
import qualified Data.Map as M
import Data.List.Split
import Control.Monad
quicksort :: (Ord a) => [(k,a)] -> [(k,a)]
quicksort [] = []
quicksort ((k,a):xs) =
let smallerSorted = quicksort [(x,y) | (x,y) <- xs, y<=a]
biggerSorted = quicksort [(x,y) | (x,y) <- xs, y>a]
in biggerSorted ++ [(k,a)] ++ smallerSorted
main = do
txt <- getContents
let wss = map (filter (\ w -> all C.isAlphaNum w && w /= "" )) $ map (splitOneOf " \t.+-*/|&^>=<\\_,.:;!?()[]{}'\",。;?!") $ lines $ map C.toLower txt
let countMap = M.fromListWith (+) $ map (\x -> (x, 1)) $ concat wss
let countList = M.toList countMap
let countSorted = quicksort countList
let maxLen = maximum $ map (\(x,_) -> length x) countList
forM countSorted (\(a,b) -> do putStrLn $ a ++ take (maxLen - length a) (repeat ' ') ++ ": " ++ (show b))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment