{"id":2510,"date":"2016-05-31T08:50:42","date_gmt":"2016-05-31T06:50:42","guid":{"rendered":"http:\/\/www.glc.us.es\/~jalonso\/exercitium\/?p=2510"},"modified":"2016-05-31T08:50:42","modified_gmt":"2016-05-31T06:50:42","slug":"sucesion-infinita-de-todas-las-palabras","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/sucesion-infinita-de-todas-las-palabras\/","title":{"rendered":"Sucesi\u00f3n infinita de todas las palabras"},"content":{"rendered":"<p>El conjunto de todas las palabras se puede ordenar como en los diccionarios:<\/p>\n<pre lang=\"text\"> \n     a,   b, ...,   z,   A,   B, ...,   Z,\n    aa,  ab, ...,  az,  aA,  aB, ...,  aZ,\n    ba,  bb, ...,  bz,  bA,  bB, ...,  bZ,\n   ...\n    za,  zb, ...,  zz,  zA,  zB, ...,  zZ,\n   aaa, aab, ..., aaz, aaA, aaB, ..., aaZ,\n   baa, bab, ..., baz, baA, baB, ..., baZ,\n   ...\n<\/pre>\n<p>Definir las funciones<\/p>\n<pre lang=\"text\"> \n   palabras :: [String]\n   posicion :: String -> Integer\n<\/pre>\n<p>tales que<\/p>\n<ul>\n<li>palabras es la lista ordenada de todas las palabras. Por ejemplo,<\/li>\n<\/ul>\n<pre lang=\"text\"> \n     \u03bb> take 10 (drop 100 palabras)\n     [\"aW\",\"aX\",\"aY\",\"aZ\",\"ba\",\"bb\",\"bc\",\"bd\",\"be\",\"bf\"]\n     \u03bb> take 10 (drop 2750 palabras)\n     [\"ZU\",\"ZV\",\"ZW\",\"ZX\",\"ZY\",\"ZZ\",\"aaa\",\"aab\",\"aac\",\"aad\"]\n     \u03bb> palabras !! (10^6)\n     \"gePO\"\n<\/pre>\n<ul>\n<li>(posicion n) es la palabra que ocupa la posici\u00f3n n en la lista ordenada de todas las palabras. Por ejemplo,<\/li>\n<\/ul>\n<pre lang=\"text\"> \n   posicion \"c\"                    ==  2\n   posicion \"ab\"                   ==  53\n   posicion \"ba\"                   ==  104\n   posicion \"eva\"                  ==  14664\n   posicion \"adan\"                 ==  151489\n   posicion \"HoyEsMartes\"          ==  4957940944437977046\n   posicion \"EnUnLugarDeLaMancha\"  ==  241779893912461058861484239910864\n<\/pre>\n<p>Comprobar con QuickCheck que para todo entero positivo n se verifica que<\/p>\n<pre lang=\"text\"> \n   posicion (palabras `genericIndex` n) == n\n<\/pre>\n<h4>Soluciones<\/h4>\n<p>[schedule expon=&#8217;2016-06-07&#8242; expat=\u00bb06:00&#8243;]<\/p>\n<ul>\n<li>Las soluciones se pueden escribir en los comentarios hasta el 07 de junio.\n<li>El c\u00f3digo se debe escribir entre una l\u00ednea con &#60;pre lang=\u00bbhaskell\u00bb&#62; y otra con &#60;\/pre&#62;\n<\/ul>\n<p>[\/schedule]<\/p>\n<p>[schedule on=&#8217;2016-06-07&#8242; at=\u00bb06:00&#8243;]<\/p>\n<pre lang=\"haskell\">\r\nimport Data.List (genericIndex, genericLength)\r\nimport Test.QuickCheck\r\n\r\n-- 1\u00aa definici\u00f3n de palabras\r\n-- =========================\r\n    \r\npalabras1 :: [String]\r\npalabras1 = concatMap palabrasDeLongitud [1..]\r\n\r\n-- (palabrasDeLongitud n) es la lista ordenada de palabras longitud\r\n-- n. Por ejemplo,\r\n--    take 3 (palabrasDeLongitud 2)  ==  [\"aa\",\"ab\",\"ac\"]\r\n--    take 3 (palabrasDeLongitud 3)  ==  [\"aaa\",\"aab\",\"aac\"]\r\npalabrasDeLongitud :: Integer -> [String]\r\npalabrasDeLongitud 1 = [[x]  | x <- letras]\r\npalabrasDeLongitud n = [x:ys | x <- letras,\r\n                               ys <- palabrasDeLongitud (n-1)]\r\n\r\n-- letras es la lista ordenada de las letras.                       \r\nletras :: [Char]\r\nletras = ['a'..'z'] ++ ['A'..'Z']\r\n\r\n-- 2\u00aa definici\u00f3n de palabras\r\n-- =========================\r\n\r\npalabras2 :: [String]\r\npalabras2 = concat (iterate f elementales)\r\n    where f = concatMap (\\x -> map (x++) elementales)\r\n\r\n-- elementales es la lista de las palabras de una letra.              \r\nelementales :: [String]            \r\nelementales = map (:[]) letras\r\n\r\n-- 3\u00aa definici\u00f3n de palabras\r\n-- =========================\r\n\r\npalabras3 :: [String]\r\npalabras3 = tail $ map reverse aux\r\n    where aux = \"\" : [c:cs | cs <- aux, c <- letras]\r\n\r\n-- Comparaci\u00f3n\r\n-- ===========\r\n\r\n--    \u03bb> palabras1 !! (10^6)\r\n--    \"gePO\"\r\n--    (0.87 secs, 480,927,648 bytes)\r\n--    \u03bb> palabras2 !! (10^6)\r\n--    \"gePO\"\r\n--    (0.11 secs, 146,879,840 bytes)\r\n--    \u03bb> palabras3 !! (10^6)\r\n--    \"gePO\"\r\n--    (0.25 secs, 203,584,608 bytes)\r\n\r\n-- 1\u00aa definici\u00f3n de posicion\r\n-- =========================\r\n\r\nposicion1 :: String -> Integer\r\nposicion1 cs = genericLength (takeWhile (\/=cs) palabras1)\r\n\r\n-- 1\u00aa definici\u00f3n de posicion\r\n-- =========================\r\n\r\nposicion2 :: String -> Integer\r\nposicion2 \"\"     = -1\r\nposicion2 (c:cs) = (1 + posicionLetra c) * 52^(length cs) + posicion2 cs\r\n\r\nposicionLetra :: Char -> Integer\r\nposicionLetra c = genericLength (takeWhile (\/=c) letras)\r\n\r\n-- La propiedad es\r\nprop_palabras :: (Positive Integer) -> Bool\r\nprop_palabras (Positive n) =\r\n    posicion2 (palabras3 `genericIndex` n) == n\r\n\r\n-- La comprobaci\u00f3n es              \r\n--    \u03bb> quickCheck prop_palabras\r\n--    +++ OK, passed 100 tests.\r\n<\/pre>\n<p>[\/schedule]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>El conjunto de todas las palabras se puede ordenar como en los diccionarios: a, b, &#8230;, z, A, B, &#8230;, Z, aa, ab, &#8230;, az, aA, aB, &#8230;, aZ, ba, bb, &#8230;, bz, bA, bB, &#8230;, bZ, &#8230; za, zb, &#8230;, zz, zA, zB, &#8230;, zZ, aaa, aab, &#8230;, aaz, aaA, aaB, &#8230;, aaZ, baa,&#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":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/2510"}],"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=2510"}],"version-history":[{"count":1,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/2510\/revisions"}],"predecessor-version":[{"id":2511,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/2510\/revisions\/2511"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/media?parent=2510"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/categories?post=2510"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/tags?post=2510"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}