{"id":6711,"date":"2022-03-01T06:00:18","date_gmt":"2022-03-01T04:00:18","guid":{"rendered":"http:\/\/www.glc.us.es\/~jalonso\/exercitium\/?p=6711"},"modified":"2022-03-08T08:33:58","modified_gmt":"2022-03-08T06:33:58","slug":"anagramas","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/anagramas\/","title":{"rendered":"Anagramas"},"content":{"rendered":"<p>Una palabra es una anagrama de otra si se puede obtener permutando sus letras. Por ejemplo, \u00abmora\u00bb y \u00abroma\u00bb son anagramas de \u00abamor\u00bb.<\/p>\n<p>Definir la funci\u00f3n<\/p>\n<pre lang=\"text\">\n   anagramas :: String -> [String] -> [String]\n<\/pre>\n<p>tal que (anagramas x ys) es la lista de los elementos de ys que son anagramas de x. Por ejemplo,<\/p>\n<pre lang=\"text\">\n   \u03bb> anagramas \"amor\" [\"Roma\",\"mola\",\"loma\",\"moRa\", \"rama\"]\n   [\"Roma\",\"moRa\"]\n   \u03bb> anagramas \"rama\" [\"aMar\",\"amaRa\",\"roMa\",\"marr\",\"aRma\"]\n   [\"aMar\",\"aRma\"]\n<\/pre>\n<h4>Soluciones<\/h4>\n<pre lang=\"haskell\">\nimport Data.List (delete, permutations, sort)\nimport Data.Char (toLower)\nimport Data.Function (on)\n\n-- 1\u00aa soluci\u00f3n\n-- =============\n\nanagramas :: String -> [String] -> [String]\nanagramas _ [] = []\nanagramas x (y:ys)\n  | sonAnagramas x y = y : anagramas x ys\n  | otherwise        = anagramas x ys\n\n-- (sonAnagramas xs ys) se verifica si xs e ys son anagramas. Por\n-- ejemplo,\n--    sonAnagramas \"amor\" \"Roma\"  ==  True\n--    sonAnagramas \"amor\" \"mola\"  ==  False\nsonAnagramas :: String -> String -> Bool\nsonAnagramas xs ys =\n  sort (map toLower xs) == sort (map toLower ys)\n\n-- 2\u00aa soluci\u00f3n\n-- =============\n\nanagramas2 :: String -> [String] -> [String]\nanagramas2 _ [] = []\nanagramas2 x (y:ys)\n  | sonAnagramas2 x y = y : anagramas2 x ys\n  | otherwise         = anagramas2 x ys\n\nsonAnagramas2 :: String -> String -> Bool\nsonAnagramas2 xs ys =\n  (sort . map toLower) xs == (sort . map toLower) ys\n\n-- 3\u00aa soluci\u00f3n\n-- ===========\n\nanagramas3 :: String -> [String] -> [String]\nanagramas3 _ [] = []\nanagramas3 x (y:ys)\n  | sonAnagramas3 x y = y : anagramas3 x ys\n  | otherwise         = anagramas3 x ys\n\nsonAnagramas3 :: String -> String -> Bool\nsonAnagramas3 = (==) `on` (sort . map toLower)\n\n-- Nota. En la soluci\u00f3n anterior se usa la funci\u00f3n on ya que\n--    (f `on` g) x y\n-- es equivalente a\n--    f (g x) (g y)\n-- Por ejemplo,\n--    \u03bb> ((*) `on` (+2)) 3 4\n--    30\n\n-- 4\u00aa soluci\u00f3n\n-- ===========\n\nanagramas4 :: String -> [String] -> [String]\nanagramas4 x ys = [y | y <- ys, sonAnagramas x y]\n\n-- 5\u00aa soluci\u00f3n\n-- ===========\n\nanagramas5 :: String -> [String] -> [String]\nanagramas5 x = filter (`sonAnagramas` x)\n\n-- 6\u00aa soluci\u00f3n\n-- ===========\n\nanagramas6 :: String -> [String] -> [String]\nanagramas6 x = filter (((==) `on` (sort . map toLower)) x)\n\n-- 7\u00aa soluci\u00f3n\n-- ===========\n\nanagramas7 :: String -> [String] -> [String]\nanagramas7 _ [] = []\nanagramas7 x (y:ys)\n  | sonAnagramas7 x y = y : anagramas7 x ys\n  | otherwise         = anagramas7 x ys\n\nsonAnagramas7 :: String -> String -> Bool\nsonAnagramas7 xs ys = aux (map toLower xs) (map toLower ys)\n  where\n    aux [] [] = True\n    aux [] _  = False\n    aux (u:us) vs | u `notElem` vs = False\n                  | otherwise      = aux us (delete u vs)\n\n-- Comparaci\u00f3n de eficiencia\n-- =========================\n\n-- La comparaci\u00f3n es\n--    \u03bb> ej = take (10^6) (permutations \"1234567890\")\n--    \u03bb> length (anagramas \"1234567890\" ej)\n--    1000000\n--    (2.27 secs, 5,627,236,104 bytes)\n--    \u03bb> length (anagramas2 \"1234567890\" ej)\n--    1000000\n--    (2.80 secs, 5,513,260,584 bytes)\n--    \u03bb> length (anagramas3 \"1234567890\" ej)\n--    1000000\n--    (1.86 secs, 5,097,260,856 bytes)\n--    \u03bb> length (anagramas4 \"1234567890\" ej)\n--    1000000\n--    (2.25 secs, 5,073,260,632 bytes)\n--    \u03bb> length (anagramas5 \"1234567890\" ej)\n--    1000000\n--    (2.14 secs, 5,009,260,616 bytes)\n--    \u03bb> length (anagramas6 \"1234567890\" ej)\n--    1000000\n--    (1.58 secs, 4,977,260,976 bytes)\n--    \u03bb> length (anagramas7 \"1234567890\" ej)\n--    1000000\n--    (6.63 secs, 6,904,821,648 bytes)\n<\/pre>\n<p>El c\u00f3digo se encuentra en <a href=\"https:\/\/github.com\/jaalonso\/Exercitium\/blob\/main\/src\/Anagramas.hs\">GitHub<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Una palabra es una anagrama de otra si se puede obtener permutando sus letras. Por ejemplo, \u00abmora\u00bb y \u00abroma\u00bb son anagramas de \u00abamor\u00bb. Definir la funci\u00f3n anagramas :: String -> [String] -> [String] tal que (anagramas x ys) es la lista de los elementos de ys que son anagramas de x. Por ejemplo, \u03bb> anagramas&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"footnotes":"","_jetpack_memberships_contains_paid_content":false},"categories":[2],"tags":[8,504,505,498,11,6],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/6711"}],"collection":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/comments?post=6711"}],"version-history":[{"count":2,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/6711\/revisions"}],"predecessor-version":[{"id":6745,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/6711\/revisions\/6745"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/media?parent=6711"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/categories?post=6711"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/tags?post=6711"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}