{"id":4189,"date":"2014-03-11T22:07:01","date_gmt":"2014-03-11T21:07:01","guid":{"rendered":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/?p=4189"},"modified":"2014-03-11T22:07:23","modified_gmt":"2014-03-11T21:07:23","slug":"i1m2013-el-triangulo-de-floyd-en-haskell","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/i1m2013-el-triangulo-de-floyd-en-haskell\/","title":{"rendered":"I1M2013: El tri\u00e1ngulo de Floyd en Haskell"},"content":{"rendered":"<p>En la segunda parte de la clase de hoy de <a href=\"http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m-13\">Inform\u00e1tica de 1\u00ba del Grado en Matem\u00e1ticas<\/a> se han explicado las soluciones del ejercicio 6 de la relaci\u00f3n 17 sobre el tri\u00e1ngulo de Floyd.<\/p>\n<p>Los ejercicios, y sus soluciones, se muestran a continuaci\u00f3n.<br \/>\n<!--more--><\/p>\n<pre lang=\"haskell\">\r\n-- ---------------------------------------------------------------------\r\n-- \u00a7 El tri\u00e1ngulo de Floyd                                            --\r\n-- ---------------------------------------------------------------------\r\n\r\n-- El tri\u00e1ngulo de Floyd, llamado as\u00ed en honor a Robert Floyd, es un\r\n-- tri\u00e1ngulo rect\u00e1ngulo formado con n\u00fameros naturales. Para crear un\r\n-- tri\u00e1ngulo de Floyd, se comienza con un 1 en la esquina superior\r\n-- izquierda, y se contin\u00faa escribiendo la secuencia de los n\u00fameros\r\n-- naturales de manera que cada l\u00ednea contenga un n\u00famero m\u00e1s que la\r\n-- anterior. Las 5 primeras l\u00edneas del tri\u00e1ngulo de Floyd son\r\n--     1\r\n--     2   3\r\n--     4   5   6\r\n--     7   8   9  10\r\n--    11  12  13  14  15\r\n-- \r\n-- El tri\u00e1ngulo de Floyd tiene varias propiedades matem\u00e1ticas\r\n-- interesantes. Los n\u00fameros del cateto de la parte izquierda forman la\r\n-- secuencia de los n\u00fameros poligonales centrales, mientras que los de\r\n-- la hipotenusa nos dan el conjunto de los n\u00fameros triangulares.\r\n\r\n-- ---------------------------------------------------------------------\r\n-- \u00a7 Librer\u00edas auxiliares                                             --\r\n-- ---------------------------------------------------------------------\r\n\r\nimport Data.Char \r\nimport Data.List \r\nimport Test.QuickCheck\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 6.1. Definir la funci\u00f3n\r\n--    siguienteF :: [Integer] -> [Integer]\r\n-- tal que (siguienteF xs) es la lista de los elementos de la l\u00ednea xs en\r\n-- el tri\u00e1ngulo de Lloyd. Por ejemplo,\r\n--    siguienteF [2,3]    ==  [4,5,6]\r\n--    siguienteF [4,5,6]  ==  [7,8,9,10]\r\n-- ---------------------------------------------------------------------\r\n\r\nsiguienteF :: [Integer] -> [Integer]\r\nsiguienteF xs = [a..a+n]\r\n    where a = 1+last xs\r\n          n = genericLength xs\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 6.2. Definir la funci\u00f3n        \r\n--    trianguloFloyd :: [[Integer]]\r\n-- tal que trianguloFloyd es el tri\u00e1ngulo de Floyd. Por ejemplo,\r\n--    ghci> take 4 trianguloFloyd\r\n--    [[1],\r\n--     [2,3],\r\n--     [4,5,6],\r\n--     [7,8,9,10]]\r\n-- ---------------------------------------------------------------------\r\n\r\ntrianguloFloyd :: [[Integer]]\r\ntrianguloFloyd = iterate siguienteF [1]\r\n\r\n-- Filas del tri\u00e1ngulo de Floyd\r\n-- ============================\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 6.3. Definir la funci\u00f3n\r\n--    filaTrianguloFloyd :: Integer -> [Integer]\r\n-- tal que (filaTrianguloFloyd n) es la fila n-\u00e9sima del tri\u00e1ngulo de\r\n-- Floyd. Por ejemplo,  \r\n--    filaTrianguloFloyd 3  ==  [4,5,6]\r\n--    filaTrianguloFloyd 4  ==  [7,8,9,10]\r\n-- ---------------------------------------------------------------------\r\n\r\nfilaTrianguloFloyd :: Integer -> [Integer]\r\nfilaTrianguloFloyd n = trianguloFloyd `genericIndex` (n-1)\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 6.4. Definir la funci\u00f3n\r\n--    sumaFilaTrianguloFloyd :: Integer -> Integer\r\n-- tal que (sumaFilaTrianguloFloyd n) es la suma de los fila n-\u00e9sima del\r\n-- tri\u00e1ngulo de Floyd. Por ejemplo,\r\n--    sumaFilaTrianguloFloyd 1  ==  1\r\n--    sumaFilaTrianguloFloyd 2  ==  5\r\n--    sumaFilaTrianguloFloyd 3  ==  15\r\n--    sumaFilaTrianguloFloyd 4  ==  34\r\n--    sumaFilaTrianguloFloyd 5  ==  65\r\n-- ---------------------------------------------------------------------\r\n\r\nsumaFilaTrianguloFloyd :: Integer -> Integer\r\nsumaFilaTrianguloFloyd = sum . filaTrianguloFloyd\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 6.5. A partir de los valores de (sumaFilaTrianguloFloyd n)\r\n-- para n entre 1 y 5, conjeturar una f\u00f3rmula para calcular\r\n-- (sumaFilaTrianguloFloyd n). \r\n-- ---------------------------------------------------------------------\r\n\r\n-- Usando Wolfram Alpha (como se indica en http:\/\/wolfr.am\/19XAl2X )\r\n-- a partir de 1, 5, 15, 34, 65, ... se obtiene la f\u00f3rmula\r\n--    (n^3+n)\/2\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejecicio 6. Comprobar con QuickCheck la conjetura obtenida en el\r\n-- ejercicio anterior.\r\n-- ---------------------------------------------------------------------\r\n\r\n-- La conjetura es\r\nprop_sumaFilaTrianguloFloyd :: Integer -> Property\r\nprop_sumaFilaTrianguloFloyd n =        \r\n    n > 0 ==> sum (filaTrianguloFloyd n) == (n^3+n) `div` 2\r\n  \r\n-- La comprobaci\u00f3n es\r\n--    ghci> quickCheck prop_sumaFilaTrianguloFloyd\r\n--    +++ OK, passed 100 tests.\r\n\r\n-- Hipotenusa del tri\u00e1ngulo de Floyd y n\u00fameros triangulares\r\n-- ========================================================\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 6.7. Definir la funci\u00f3n\r\n--    hipotenusaFloyd :: [Integer]\r\n-- tal que hipotenusaFloyd es la lista de los elementos de la hipotenusa\r\n-- del tri\u00e1ngulo de Floyd. Por ejemplo, \r\n--    take 5 hipotenusaFloyd  ==  [1,3,6,10,15]\r\n-- ---------------------------------------------------------------------\r\n\r\nhipotenusaFloyd :: [Integer]\r\nhipotenusaFloyd = map last trianguloFloyd\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 6.8. Lo n\u00fameros triangulares se forman como sigue\r\n--    *     *      * \r\n--         * *    * *\r\n--               * * *\r\n--    1     3      6\r\n-- \r\n-- La sucesi\u00f3n de los n\u00fameros triangulares se obtiene sumando los\r\n-- n\u00fameros naturales. As\u00ed, los 5 primeros n\u00fameros triangulares son\r\n--     1 = 1\r\n--     3 = 1+2\r\n--     6 = 1+2+3\r\n--    10 = 1+2+3+4\r\n--    15 = 1+2+3+4+5\r\n-- \r\n-- Definir la funci\u00f3n\r\n--    triangulares :: [Integer]\r\n-- tal que triangulares es la lista de los n\u00fameros triangulares. Por\r\n-- ejemplo, \r\n--    take 10 triangulares  ==  [1,3,6,10,15,21,28,36,45,55]\r\n-- ---------------------------------------------------------------------\r\n\r\ntriangulares :: [Integer]\r\ntriangulares = 1 : [x+y | (x,y) <- zip [2..] triangulares]\r\n\r\n-- 2\u00aa definici\u00f3n (usando scanl):\r\ntriangulares2 :: [Integer]\r\ntriangulares2 = scanl (+) 1 [2..]\r\n\r\n-- 3\u00aa definici\u00f3n (usando la f\u00f3rmula de la suma de la progresi\u00f3n):\r\ntriangulares3 :: [Integer]\r\ntriangulares3 = [(n*(n+1)) `div` 2 | n <- [1..]]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 6.9. Definir la funci\u00f3n \r\n--    prop_hipotenusaFloyd :: Int -> Bool\r\n-- tal que (prop_hipotenusaFloyd n) se verifica si los n primeros\r\n-- elementos de la hipotenusa del tri\u00e1ngulo de Floy son los primeros n\r\n-- n\u00fameros triangulares. \r\n-- \r\n-- Comprobar la propiedad para los 1000 primeros elementos.\r\n-- ---------------------------------------------------------------------\r\n\r\n-- La propiedad es\r\nprop_hipotenusaFloyd :: Int -> Bool\r\nprop_hipotenusaFloyd n = \r\n    take n hipotenusaFloyd == take n triangulares\r\n\r\n-- La comprobaci\u00f3n es\r\n--    ghci> prop_hipotenusaFloyd 1000\r\n--    True\r\n\r\n-- Cateto del tri\u00e1ngulo de Floyd y n\u00fameros poligonales centrales\r\n-- =============================================================\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 6.10. Definir la funci\u00f3n\r\n--    catetoFloyd :: [Integer]\r\n-- tal que catetoFloyd es la lista de los elementos del cateto izquierdo\r\n-- del tri\u00e1ngulo de Floyd. Por ejemplo, \r\n--    take 5 catetoFloyd  ==  [1,2,4,7,11]\r\n-- ---------------------------------------------------------------------\r\n\r\ncatetoFloyd :: [Integer]\r\ncatetoFloyd = map head trianguloFloyd\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 6.11. El n-\u00e9simo n\u00famero poligonal centrado es el m\u00e1ximo\r\n-- n\u00famero de piezas que se pueden obtener a partir de un c\u00edrculo con n\r\n-- l\u00edneas rectas. Por ejemplo,\r\n--    poligonales_centrados.jpg\r\n--\r\n-- Definir la funci\u00f3n\r\n--    poligonalCentrado :: Integer -> Integer\r\n-- tal que (poligonalCentrado n) es el n-\u00e9simo n\u00famero poligonal\r\n-- centrado. Por ejemplo, \r\n--    [poligonalCentrado n | n <- [0..5]]  ==  [1,2,4,7,11,16]\r\n-- ---------------------------------------------------------------------\r\n\r\npoligonalCentrado :: Integer -> Integer\r\npoligonalCentrado 0 = 1\r\npoligonalCentrado n = n + poligonalCentrado (n-1)\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 6.12. Definir la funci\u00f3n\r\n--    poligonalesCentrados :: [Integer]\r\n-- tal que poligonalesCentrados es la lista de los n\u00fameros poligonales\r\n-- centrados. Por ejemplo, \r\n--    take 10 poligonalesCentrados  ==  [1,3,6,10,15,21,28,36,45,55]\r\n-- ---------------------------------------------------------------------\r\n\r\n-- 1\u00aa definici\u00f3n:\r\npoligonalesCentrados1 :: [Integer]\r\npoligonalesCentrados1 = [poligonalCentrado n | n <- [0..]]\r\n\r\n-- 2\u00aa definici\u00f3n (usando scanl):\r\npoligonalesCentrados :: [Integer]\r\npoligonalesCentrados = scanl (+) 1 [1..]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 6.13. Definir la funci\u00f3n \r\n--    prop_catetoFloyd :: Int -> Bool\r\n-- tal que (prop_catetoFloyd n) se verifica si los n primeros\r\n-- elementos del cateto izquierdo del tri\u00e1ngulo de Floy son los primeros\r\n-- n n\u00fameros poligonales centrados.\r\n-- \r\n-- Comprobar la propiedad para los 1000 primeros elementos.\r\n-- ---------------------------------------------------------------------\r\n\r\n-- La propiedad es\r\nprop_catetoFloyd :: Int -> Bool\r\nprop_catetoFloyd n = \r\n    take n catetoFloyd == take n poligonalesCentrados\r\n\r\n-- La comprobaci\u00f3n es\r\n--    ghci> prop_catetoFloyd 1000\r\n--    True\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>En la segunda parte de la clase de hoy de Inform\u00e1tica de 1\u00ba del Grado en Matem\u00e1ticas se han explicado las soluciones del ejercicio 6 de la relaci\u00f3n 17 sobre el tri\u00e1ngulo de Floyd. Los ejercicios, y sus soluciones, se muestran a continuaci\u00f3n.<\/p>\n","protected":false},"author":2,"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":[222],"tags":[270,300,194,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\/4189"}],"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=4189"}],"version-history":[{"count":2,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/4189\/revisions"}],"predecessor-version":[{"id":4191,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/4189\/revisions\/4191"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/media?parent=4189"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/categories?post=4189"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/tags?post=4189"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}