-- | -- Module : Anagramas -- Description : Selección de anagramas. -- Copyright : Exercitium (29-04-17) -- License : GPL-3 -- Maintainer : JoseA.Alonso@gmail.com -- -- Una palabra es una anagrama de otra si se puede obtener permutando -- sus letras. Por ejemplo, "mora" y "roma" son anagramas de "amor". -- -- Definir la función -- -- > anagramas :: String -> [String] -> [String] -- -- tal que (anagramas x ys) es la lista de los elementos de ys que son -- anagramas de x. Por ejemplo, -- -- >>> anagramas "amor" ["Roma","mola","loma","moRa", "rama"] -- ["Roma","moRa"] -- >>> anagramas "rama" ["aMar","amaRa","roMa","marr","aRma"] -- ["aMar","aRma"] module Anagramas where import Data.List (sort) import Data.Char (toLower) import Data.Function (on) -- | 1ª definición (por recursión): anagramas :: String -> [String] -> [String] anagramas _ [] = [] anagramas x (y:ys) | sonAnagramas x y = y : anagramas x ys | otherwise = anagramas x ys -- | (sonAnagramas xs ys) se verifica si xs e ys son anagramas. Por -- ejemplo, -- -- >>> sonAnagramas "amor" "Roma" -- True -- >>> sonAnagramas "amor" "mola" -- False sonAnagramas :: String -> String -> Bool sonAnagramas xs ys = sort (map toLower xs) == sort (map toLower ys) -- | 2ª definición de sonAnagramas sonAnagramas2 :: String -> String -> Bool sonAnagramas2 xs ys = (sort . map toLower) xs == (sort . map toLower) ys -- | 3ª definición de sonAnagramas (con on) sonAnagramas3 :: String -> String -> Bool sonAnagramas3 = (==) `on` (sort . map toLower) -- | Comprobación de la equivalencia de las definiciones de anagramas. -- -- >>> verifica_sonAnagramas -- True verifica_sonAnagramas :: Bool verifica_sonAnagramas = and [f "amor" "Roma" && not (f "amor" "mola") | f <- [ sonAnagramas , sonAnagramas2 , sonAnagramas3 ]] -- | 2ª definición (por comprensión) anagramas2 :: String -> [String] -> [String] anagramas2 x ys = [y | y <- ys, sonAnagramas x y] -- | 3ª definición (con filter y sin el 2ª argumento) anagramas3 :: String -> [String] -> [String] anagramas3 x = filter (`sonAnagramas` x) -- | 4ª definición (sin sonAnagramas ni el 2º argumento) anagramas4 :: String -> [String] -> [String] anagramas4 x = filter (((==) `on` (sort . map toLower)) x) -- | Comprobación de la equivalencia de las definiciones de anagramas. -- -- >>> verifica_anagramas -- True verifica_anagramas :: Bool verifica_anagramas = and [f "amor" ["Roma","mola","loma","moRa", "rama"] == ["Roma","moRa"] && f "rama" ["aMar","amaRa","roMa","marr","aRma"] == ["aMar","aRma"] | f <- [ anagramas , anagramas2 , anagramas3 , anagramas4 ]]