Skip to content

Instantly share code, notes, and snippets.

@marianocordoba
Last active February 21, 2018 02:50
Show Gist options
  • Save marianocordoba/58782f9c1b5cda2062343fb5bca30e2f to your computer and use it in GitHub Desktop.
Save marianocordoba/58782f9c1b5cda2062343fb5bca30e2f to your computer and use it in GitHub Desktop.
TopWords
import System.Environment
import System.Exit
import Data.Char
import Data.List
import Data.Tuple
import Data.List.Split
import qualified Data.Map.Strict as Map
main = getArgs >>= parseArgs
-- | Interpreta los argumentos
parseArgs ["-h"] = usage >> exit
parseArgs ["-v"] = version >> exit
parseArgs [f] = do
putStrLn $ "Las palabras que más se repiten en \"" ++ f ++ "\" son: "
mapM_ (putStrLn . format) =<< top10 <$> foldl add Map.empty <$> words <$> map toUpper <$> readFile f
parseArgs _ = usage >> exit
-- | Imprime instrucciones de uso.
usage = putStrLn "Usage: tw FILE"
-- | Imprime versión y copyright.
version = putStrLn "TopWords v0.1" >> putStrLn "(C) 2018 Mariano Córdoba"
-- | Termina el programa correctamente.
exit = exitWith ExitSuccess
-- | Está función devuelve un String con el formato adecuado para mostrar los
-- resultados.
format t = "\"" ++ word ++ "\" con " ++ (show count) ++ occurrences where
word = snd t
count = fst t
occurrences
| count == 1 = " ocurrencia."
| otherwise = " ocurrencias."
-- | Agrega una clave al diccionario. Si dicha clave existe, incrementa su
-- valor.
add :: Map.Map String Int -> String -> Map.Map String Int
add m k
| Map.member k m = Map.adjust (+1) k m
| otherwise = Map.insert k 1 m
-- | Obtiene los 10 elementos de mayor valor del diccionario.
top10 :: Map.Map String Int -> [(Int, String)]
top10 m = take 10 $ reverse $ sort $ map swap $ Map.toList m
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment