{"id":2526,"date":"2013-02-23T06:42:56","date_gmt":"2013-02-23T06:42:56","guid":{"rendered":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/?p=2526"},"modified":"2013-03-16T07:40:51","modified_gmt":"2013-03-16T07:40:51","slug":"una-curiosa-propiedad-del-123-en-haskell","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/una-curiosa-propiedad-del-123-en-haskell\/","title":{"rendered":"Una curiosa propiedad del 123 en Haskell"},"content":{"rendered":"<p>Esta semana se ha publicado en <a href=\"http:\/\/gaussianos.com\">Gaussianos<\/a> el art\u00edculo <a href=\"http:\/\/gaussianos.com\/una-curiosa-propiedad-del-123\/\">Una curiosa propiedad del 123<\/a>. A partir de dicho art\u00edculo he elaborado la siguiente relaci\u00f3n de ejercicios de Haskell para la asignatura de <a href=\"http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m\">Inform\u00e1tica de 1\u00ba del Grado en Matem\u00e1ticas<\/a>.<br \/>\n<!--more--><\/p>\n<pre lang=\"haskell\">\r\n-- ---------------------------------------------------------------------\r\n-- Librer\u00edas auxiliares                                               --\r\n-- ---------------------------------------------------------------------\r\n\r\nimport Data.List\r\nimport Test.QuickCheck\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 1. Definir la funci\u00f3n\r\n--    cifras :: Integer -> [Int]\r\n-- tal que (cifras n) es la lista de las cifras del n\u00famero n. Por\r\n-- ejemplo, \r\n--    cifras 325352  ==  [3,2,5,3,5,2]\r\n-- ---------------------------------------------------------------------\r\n\r\ncifras :: Integer -> [Int]\r\ncifras n = [read [d] | d <- show n]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 2. Definir la funci\u00f3n\r\n--    siguiente :: Integer -> Integer\r\n-- tal que (siguiente n) es el n\u00famero obtenido a partir de n colocando\r\n-- primero la cantidad de cifras pares de n, despu\u00e9s la cantidad de\r\n-- cifras impares de n y despu\u00e9s la cantidad total de cifras de n. Por\r\n-- ejemplo, \r\n--    siguiente 863113  ==  246\r\n--    siguiente 246     ==  303\r\n--    siguiente 303     ==  123\r\n--    siguiente 123     ==  123\r\n-- ---------------------------------------------------------------------\r\n\r\nsiguiente :: Integer -> Integer\r\nsiguiente x = 100*p + 10*(n-p) + n\r\n    where cs = cifras x\r\n          n  = genericLength cs\r\n          p  = genericLength [c | c <- cs, even c]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 3. Definir la funci\u00f3n\r\n--    esFijo :: Integer -> Bool\r\n-- tal que (esFijo n) se verifica si n es un punto fijo; es decir, si n\r\n-- es igual que (siguiente n). Por ejemplo,\r\n--    esFijo 123  ==  True\r\n--    esFijo 303  ==  False\r\n-- ---------------------------------------------------------------------\r\n\r\nesFijo :: Integer -> Bool\r\nesFijo n = n == siguiente n\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 4. Definir la funci\u00f3n\r\n--    puntoFijo :: Integer -> Integer\r\n-- tal que (puntoFijo n) es el primer punto fijo al que se llega a\r\n-- partir de n aplicando la funci\u00f3n siguiente. Por ejemplo,\r\n--    puntoFijo 863113  ==  123\r\n-- ya que, aplicando siguiente, se tiene la siguiente sucesi\u00f3n  \r\n--    863113 -> 246 -> 303 -> 123   \r\n-- y 123 es un punto fijo.\r\n-- ---------------------------------------------------------------------\r\n\r\npuntoFijo :: Integer -> Integer\r\npuntoFijo n | esFijo n  = n\r\n            | otherwise = puntoFijo (siguiente n)\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 5. Calcular el punto fijo de los 15 primeros n\u00fameros\r\n-- naturales. \r\n-- ---------------------------------------------------------------------\r\n\r\n-- El c\u00e1lculo es\r\n--    ghci> [puntoFijo n | n <- [0..14]]\r\n--    [123,123,123,123,123,123,123,123,123,123,123,123,123,123,123]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 6. A partir del c\u00e1lculo anterior, conjeturar el valor de\r\n-- (puntoFijo n) y verificarlo con QuickCheck.\r\n-- ---------------------------------------------------------------------\r\n\r\n-- La conjetura es que para todo n\u00famero natural n, el valor de\r\n-- (puntoFijo n) es 123. Su expresi\u00f3n es\r\n\r\nprop_puntoFijo :: Integer -> Property\r\nprop_puntoFijo n = \r\n    n >= 0 ==> puntoFijo n == 123\r\n\r\n-- La comprobaci\u00f3n es\r\n--    ghci> quickCheck prop_puntoFijo\r\n--    +++ OK, passed 100 tests.\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 7. Definir la funci\u00f3n\r\n--    pasos :: Integer -> [Integer]\r\n-- tal que (pasos n) es una lista de n\u00fameros tal que el primero es n, el\r\n-- 2\u00ba es el siguiente del 1\u00ba, el 3\u00ba es el siguiente de 2\u00ba y as\u00ed\r\n-- sucesivamente hasta que se llega a un punto fijo. Por ejemplo,   \r\n--    pasos 863113  ==  [863113,246,303,123]\r\n-- ---------------------------------------------------------------------\r\n\r\npasos :: Integer -> [Integer]\r\npasos n | esFijo n  = [n]\r\n        | otherwise = n : pasos (siguiente n)\r\n           \r\n-- Otra definici\u00f3n equivalente es\r\npasos' :: Integer -> [Integer]\r\npasos' n = takeWhile (\/=123) (iterate siguiente n) ++ [123]\r\n           \r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 8. Definir la funci\u00f3n\r\n--    nPasos :: Integer -> Integer\r\n-- tal que (pasos n) es el n\u00famero de veces que hay que aplicar el\r\n-- siguiente, a partir de n, para llegar a un punto fijo. Por ejemplo,   \r\n--    nPasos 863113  ==  3\r\n-- ---------------------------------------------------------------------\r\n\r\n-- Usando la funci\u00f3n pasos\r\nnPasos :: Integer -> Integer\r\nnPasos n = genericLength (pasos n) - 1\r\n\r\n-- Sin usar pasos\r\nnPasos' :: Integer -> Integer\r\nnPasos' n | esFijo n  = 0\r\n          | otherwise = 1 + nPasos' (siguiente n)\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 9. Comprobar, con QuickCheck, que para todo n\u00famero\r\n-- natural n, (nPasos n) es menor que 6.\r\n-- ---------------------------------------------------------------------\r\n\r\n-- La propiedad es\r\nprop_nPasos :: Integer -> Property                 \r\nprop_nPasos n = \r\n  n >= 0 ==> nPasos n < 6\r\n  \r\n-- La comprobaci\u00f3n es\r\n--    ghci> quickCheck prop_nPasos\r\n--    +++ OK, passed 100 tests.\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 10. Demostrar, por evaluaci\u00f3n, que para todos los naturales\r\n-- n hasta 999 se tiene que (nPasos n) < 6.\r\n-- ---------------------------------------------------------------------\r\n\r\n-- La propiedad es \r\nprop_nPasos1 :: Bool\r\nprop_nPasos1 =               \r\n  and [nPasos n < 6 | n <- [0..999]]\r\n  \r\n-- La comprobaci\u00f3n es \r\n--    ghci> prop_nPasos1\r\n--    True\r\n\r\n-- Otra forma de demostrarlo es mediante la siguiente tabla, donde la 1\u00aa\r\n-- columna indica el n\u00famero de cifras, la 2\u00aa el n\u00famero de cifras pares,\r\n-- la 3\u00aa el n\u00famero de cifras impares, la 4\u00aa la lista de los pasos y la\r\n-- 5\u00aa el n\u00famero de Pasos:\r\n--    cifras | pares | impares | pasos                 | nPasos\r\n--    1      | 0     | 1       | [n,11,22,202,303,123] | 5\r\n--           | 1     | 0       | [n,101,123]           | 3\r\n--    2      | 0     | 2       | [n,22,202,303,123]    | 4\r\n--           | 1     | 1       | [n,112,123]           | 3\r\n--           | 2     | 0       | [n,202,303,123]       | 3\r\n--    3      | 0     | 3       | [n,33,22,202,303,123] | 5\r\n--           | 1     | 2       | [n,123]               | 1 * \r\n--           | 2     | 1       | [n,213,123]           | 2\r\n--           | 3     | 0       | [n,303,123]           | 2\r\n-- La excepci\u00f3n * es para el 123 ya que (pasos 123) = [1,2,3]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 11. Definir las funciones \r\n--    unidades :: Integer -> Integer\r\n--    decenas :: Integer -> Integer\r\n--    centenas :: Integer -> Integer\r\n-- tales que \r\n-- * (unidades x) es la cifra de las unidades de x,\r\n-- * (decenas x)  es la cifra de las decenas  de x,\r\n-- * (centenas x) es la cifra de las centenas de x,\r\n-- Por ejemplo,\r\n--    unidades 1234  ==  4\r\n--    decenas  1234  ==  3\r\n--    centenas 1234  ==  2\r\n--    unidades   34  ==  4\r\n--    decenas    34  ==  3\r\n--    centenas   34  ==  0\r\n-- ---------------------------------------------------------------------\r\n\r\nunidades :: Integer -> Integer\r\nunidades x = mod x 10\r\n\r\ndecenas :: Integer -> Integer\r\ndecenas x  = mod (div x 10) 10\r\n\r\ncentenas :: Integer -> Integer\r\ncentenas x = mod (div x 100) 10\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 12. Definir la funci\u00f3n \r\n--    esSiguiente :: Integer -> Bool\r\n-- tal que (esSiguiente n) se verifica si existe un x tal que n es el\r\n-- siguiente de x. Por ejemplo,\r\n--    esSiguiente 134  ==  True\r\n--    esSiguiente 124  ==  False\r\n--    esSiguiente 33   ==  True\r\n--    esSiguiente 34   ==  False\r\n-- ---------------------------------------------------------------------\r\n\r\nesSiguiente :: Integer -> Bool\r\nesSiguiente n = unidades n == decenas n + centenas n\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 13. Definir la funci\u00f3n\r\n--    listaAnumero :: [Integer] -> Integer\r\n-- tal que (listaAnumero xs) es el n\u00famero correspondiente a la lista de\r\n-- cifras xs. Por ejemplo, \r\n--    listaAnumero [3,0,5]  ==  305\r\n-- ---------------------------------------------------------------------\r\n\r\nlistaAnumero :: [Integer] -> Integer\r\nlistaAnumero xs = aux (reverse xs)\r\n  where aux [x]    = x\r\n        aux (x:xs) = x + 10 * (aux xs)\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 14. Definir la funci\u00f3n\r\n--    anterior :: Integer -> Integer\r\n-- tal que (anterior n) es un n\u00famero x tal que el siguiente de x\r\n-- es n. Por ejemplo, \r\n--    anterior 235  ==  11122\r\n--    anterior  44  ==  1111\r\n-- ---------------------------------------------------------------------        \r\n\r\nanterior :: Integer -> Integer\r\nanterior n = listaAnumero ((replicate y 1) ++ (replicate x 2))\r\n  where x = fromIntegral (centenas n)\r\n        y = fromIntegral (decenas n)\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 15. Comprobar, con QuickCheck, que para todo n\u00famero\r\n-- natural n, \r\n--    siguiente (anterior x) == x        \r\n-- donde x es el siguiente de n.        \r\n-- ---------------------------------------------------------------------        \r\n        \r\n-- La propiedad\r\nprop_anterior :: Integer -> Property        \r\nprop_anterior n =\r\n  n >= 0 ==> siguiente (anterior x) == x\r\n  where x = siguiente n\r\n \r\n-- La comprobaci\u00f3n es        \r\n--    ghci> quickCheck prop_anterior\r\n--    +++ OK, passed 100 tests.\r\n        \r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 16. Demostrar, por evaluaci\u00f3n, que para todo n\u00famero\r\n-- natural n menor que 100, si (nPasos n) es 5 entonces no existe ning\u00fan\r\n-- x tal que n es el siguiente de x.\r\n-- ---------------------------------------------------------------------\r\n\r\n-- La propiedad es\r\nprop_largos :: Bool\r\nprop_largos =\r\n  null [n | n <- [0..999], nPasos n == 5, esSiguiente n]\r\n  \r\n-- La comprobaci\u00f3n es  \r\n--    ghci> prop_largos\r\n--    True\r\n        \r\n-- Nota. Como consecuencia de los ejercicios 10 y 16 se tiene que para\r\n-- todo n\u00famero natural n, (nPasos n) es menor que 6.\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Esta semana se ha publicado en Gaussianos el art\u00edculo Una curiosa propiedad del 123. A partir de dicho art\u00edculo he elaborado la siguiente relaci\u00f3n de ejercicios de Haskell para la asignatura de Inform\u00e1tica de 1\u00ba del Grado en Matem\u00e1ticas.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","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":[1],"tags":[270,126],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_likes_enabled":false,"_links":{"self":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/2526"}],"collection":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/comments?post=2526"}],"version-history":[{"count":7,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/2526\/revisions"}],"predecessor-version":[{"id":3129,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/2526\/revisions\/3129"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/media?parent=2526"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/categories?post=2526"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/tags?post=2526"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}