{"id":4097,"date":"2014-02-05T07:53:16","date_gmt":"2014-02-05T06:53:16","guid":{"rendered":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/?p=4097"},"modified":"2014-02-12T08:32:44","modified_gmt":"2014-02-12T07:32:44","slug":"el-triangulo-de-floyd-en-haskell","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/el-triangulo-de-floyd-en-haskell\/","title":{"rendered":"El tri\u00e1ngulo de Floyd en Haskell"},"content":{"rendered":"<p>El <a href=\"http:\/\/bit.ly\/1hhIkHv\">tri\u00e1ngulo de Floyd<\/a>, llamado as\u00ed en honor a Robert Floyd, es un tri\u00e1ngulo rect\u00e1ngulo formado con n\u00fameros naturales. Para crear un tri\u00e1ngulo de Floyd, se comienza con un 1 en la esquina superior izquierda, y se contin\u00faa escribiendo la secuencia de los n\u00fameros naturales de manera que cada l\u00ednea contenga un n\u00famero m\u00e1s que la anterior. Las 5 primeras l\u00edneas del tri\u00e1ngulo de Floyd son<\/p>\n<pre lang=\"shell\">\r\n 1\r\n 2   3\r\n 4   5   6\r\n 7   8   9  10\r\n11  12  13  14  15\r\n<\/pre>\n<p>El tri\u00e1ngulo de Floyd tiene varias propiedades matem\u00e1ticas interesantes:<\/p>\n<ul>\n<li>los n\u00fameros de la hipotenusa es la sucesi\u00f3n de los n\u00fameros triangulares; es decir, los n\u00fameros que puede ser representado como puntos dispuestos en forma de tri\u00e1ngulo, empezando por el 1. Los primeros n\u00fameros triangulares son<br \/>\n<!--triangulares.gif--><br \/>\n<a href=\"https:\/\/i0.wp.com\/www.glc.us.es\/~jalonso\/vestigium\/wp-content\/uploads\/2014\/01\/triangulares.gif?ssl=1\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.glc.us.es\/~jalonso\/vestigium\/wp-content\/uploads\/2014\/01\/triangulares.gif?resize=500%2C77&#038;ssl=1\" alt=\"triangulares\" width=\"500\" height=\"77\" class=\"aligncenter size-full wp-image-4070\" data-recalc-dims=\"1\" \/><\/a> <\/p>\n<li>los n\u00fameros del cateto de la parte izquierda es la sucesi\u00f3n de los n\u00fameros poligonales centrales; donde el n-\u00e9simo n\u00famero poligonal centrado es el m\u00e1ximo n\u00famero de piezas que se pueden obtener a partir de un c\u00edrculo con n l\u00edneas rectas. Los primeros n\u00fameros poligonales centrados son<br \/>\n<!--poligonales_centrados.jpg--><br \/>\n<a href=\"https:\/\/i0.wp.com\/www.glc.us.es\/~jalonso\/vestigium\/wp-content\/uploads\/2014\/02\/poligonales_centrados.jpg?ssl=1\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.glc.us.es\/~jalonso\/vestigium\/wp-content\/uploads\/2014\/02\/poligonales_centrados.jpg?resize=580%2C226&#038;ssl=1\" alt=\"poligonales_centrados\" width=\"580\" height=\"226\" class=\"aligncenter size-full wp-image-4099\" srcset=\"https:\/\/i0.wp.com\/www.glc.us.es\/~jalonso\/vestigium\/wp-content\/uploads\/2014\/02\/poligonales_centrados.jpg?w=580&amp;ssl=1 580w, https:\/\/i0.wp.com\/www.glc.us.es\/~jalonso\/vestigium\/wp-content\/uploads\/2014\/02\/poligonales_centrados.jpg?resize=300%2C116&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.glc.us.es\/~jalonso\/vestigium\/wp-content\/uploads\/2014\/02\/poligonales_centrados.jpg?resize=150%2C58&amp;ssl=1 150w, https:\/\/i0.wp.com\/www.glc.us.es\/~jalonso\/vestigium\/wp-content\/uploads\/2014\/02\/poligonales_centrados.jpg?resize=400%2C155&amp;ssl=1 400w\" sizes=\"(max-width: 580px) 100vw, 580px\" data-recalc-dims=\"1\" \/><\/a>\n<\/ul>\n<p>En la siguiente relaci\u00f3n de ejercicios (elaborada para <a href=\"http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m\">I1M<\/a>) se define en Haskell el tri\u00e1gulo de Floyd y se comprueban algunas de sus propiedades.<br \/>\n<!--more--><\/p>\n<pre lang=\"haskell\">\r\n-- ---------------------------------------------------------------------\r\n-- \u00a7 Librer\u00edas auxiliares                                             --\r\n-- ---------------------------------------------------------------------\r\n\r\nimport Test.QuickCheck\r\nimport Data.List\r\n\r\n-- ---------------------------------------------------------------------\r\n-- \u00a7 Tri\u00e1gulo de Floyd                                                --\r\n-- ---------------------------------------------------------------------\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 1. Definir la funci\u00f3n\r\n--    siguiente :: [Integer] -> [Integer]\r\n-- tal que (siguiente xs) es la lista de los elementos de la l\u00ednea xs en\r\n-- el tri\u00e1ngulo de Lloyd. Por ejemplo,\r\n--    siguiente [2,3]    ==  [4,5,6]\r\n--    siguiente [4,5,6]  ==  [7,8,9,10]\r\n-- ---------------------------------------------------------------------\r\n\r\nsiguiente :: [Integer] -> [Integer]\r\nsiguiente xs = [a..a+n]\r\n    where a = 1+last xs\r\n          n = genericLength xs\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 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 siguiente [1]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- \u00a7 Filas del tri\u00e1ngulo de Floyd                                     --\r\n-- ---------------------------------------------------------------------\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 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 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 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-- ---------------------------------------------------------------------\r\n-- \u00a7 Hipotenusa del tri\u00e1ngulo de Floyd y n\u00fameros triangulares         --\r\n-- ---------------------------------------------------------------------\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 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 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 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-- ---------------------------------------------------------------------\r\n-- \u00a7 Cateto del tri\u00e1ngulo de Floyd y n\u00fameros poligonales centrales    --\r\n-- ---------------------------------------------------------------------\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 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 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--    Triangulo_de_Floyd_poligonales.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 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 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<p><b>Fuente<\/b><\/p>\n<ul>\n<li>Wikipedia. <a href=\"http:\/\/bit.ly\/1hhIkHv\">Tri\u00e1ngulo de Floyd<\/a>.\n<li>Wikipedia. <a href=\"http:\/\/bit.ly\/1mRaMRC\">N\u00famero triangular<\/a>.\n<li>NextNumber <a href=\"http:\/\/bit.ly\/1blG7XL\">Central polygonal numbers<\/a>.\n<li>OEIS <a href=\"http:\/\/bit.ly\/1blGdP4\">Central polygonal numbers<\/a>.\n<\/ul>\n<p><b>Destino:<\/b>La anterior relaci\u00f3n de ejercicios la ha elaborado para <\/p>\n<ul>\n<li>la asignatura de <a href=\"http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m\">Inform\u00e1tica de 1\u00ba del Grado en Matem\u00e1ticas<\/a> y\n<li>la ampliaci\u00f3n del libro <a href=\"http:\/\/www.cs.us.es\/~jalonso\/publicaciones\/Piensa_en_Haskell.pdf\">Piensa en Haskell<\/a>.\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>El tri\u00e1ngulo de Floyd, llamado as\u00ed en honor a Robert Floyd, es un tri\u00e1ngulo rect\u00e1ngulo formado con n\u00fameros naturales. Para crear un tri\u00e1ngulo de Floyd, se comienza con un 1 en la esquina superior izquierda, y se contin\u00faa escribiendo la secuencia de los n\u00fameros naturales de manera que cada l\u00ednea contenga un n\u00famero m\u00e1s que&#8230;<\/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":[221],"tags":[270,299,126,83],"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\/4097"}],"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=4097"}],"version-history":[{"count":2,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/4097\/revisions"}],"predecessor-version":[{"id":4100,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/4097\/revisions\/4100"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/media?parent=4097"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/categories?post=4097"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/tags?post=4097"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}