{"id":4083,"date":"2014-02-03T23:55:43","date_gmt":"2014-02-03T22:55:43","guid":{"rendered":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/?p=4083"},"modified":"2014-02-12T08:34:06","modified_gmt":"2014-02-12T07:34:06","slug":"numeros-poligonales-y-sus-propiedades-en-haskell","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/numeros-poligonales-y-sus-propiedades-en-haskell\/","title":{"rendered":"N\u00fameros poligonales y sus propiedades en Haskell"},"content":{"rendered":"<p>Un n\u00famero poligonal es aquel que puede ser representado como puntos dispuestos en forma de pol\u00edgono regular, empezando por el 1. Los primeros n\u00fameros poligonales son los n\u00fameros triangulares, estos se forman a partir de tri\u00e1ngulos.<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><br \/>\nLos siguientes son los n\u00fameros cuadrangulares<br \/>\n<a href=\"https:\/\/i0.wp.com\/www.glc.us.es\/~jalonso\/vestigium\/wp-content\/uploads\/2014\/02\/cuadrados.gif?ssl=1\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.glc.us.es\/~jalonso\/vestigium\/wp-content\/uploads\/2014\/02\/cuadrados.gif?resize=500%2C86&#038;ssl=1\" alt=\"cuadrados\" width=\"500\" height=\"86\" class=\"aligncenter size-full wp-image-4089\" data-recalc-dims=\"1\" \/><\/a><br \/>\nLos siguientes son los n\u00fameros pentagonales<br \/>\n<a href=\"https:\/\/i0.wp.com\/www.glc.us.es\/~jalonso\/vestigium\/wp-content\/uploads\/2014\/02\/pentagonales2.gif?ssl=1\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.glc.us.es\/~jalonso\/vestigium\/wp-content\/uploads\/2014\/02\/pentagonales2.gif?resize=500%2C125&#038;ssl=1\" alt=\"pentagonales\" width=\"500\" height=\"125\" class=\"aligncenter size-full wp-image-4094\" data-recalc-dims=\"1\" \/><\/a><\/p>\n<p>Los n\u00fameros triangulares son 1, 3, 6, 10, 15, 21, &#8230; Sus diferencias son 2, 3, 4, 5, 6, &#8230; Por tanto, se obtienen como sigue<\/p>\n<blockquote><p>\n    1 = 1<br \/>\n    3 = 1+2<br \/>\n    6 = 1+2+3<br \/>\n   10 = 1+2+3+4<br \/>\n   15 = 1+2+3+4+5<br \/>\n   21 = 1+2+3+4+5+6\n<\/p><\/blockquote>\n<p>Los n\u00fameros cuadrangulares son 1, 4, 9, 16, 25, 36, 49, &#8230; Sus diferencias son 3, 5, 7, 9, &#8230; Por tanto, se obtienen como sigue<\/p>\n<blockquote><p>\n    1 = 1<br \/>\n    4 = 1+3<br \/>\n    9 = 1+3+5<br \/>\n   16 = 1+3+5+7<br \/>\n   25 = 1+3+5+7+9<br \/>\n   36 = 1+3+5+7+9+11<br \/>\n   49 = 1+3+5+7+9+11+13\n<\/p><\/blockquote>\n<p>Los n\u00fameros pentagonales son 1, 5, 12, 22, 35, &#8230; Sus diferencias son 4, 7, 10, 13, &#8230; Por tanto, se obtienen como sigue<\/p>\n<blockquote><p>\n    1 = 1<br \/>\n    5 = 1+4<br \/>\n   12 = 1+4+7<br \/>\n   22 = 1+4+7+10<br \/>\n   35 = 1+4+7+10+13\n<\/p><\/blockquote>\n<p>Siguiendo el mismo patr\u00f3n, las diferencias entre los n\u00fameros hexagonales son 5, 9, 13, 17, &#8230; Por tanto, los primeros n\u00fameros hexagonales son<\/p>\n<blockquote><p>\n    1 = 1<br \/>\n    6 = 1+5<br \/>\n   15 = 1+5+9<br \/>\n   28 = 1+5+9+13<br \/>\n   45 = 1+5+9+13+17\n<\/p><\/blockquote>\n<p>Continuando con este patr\u00f3n se obtienen los n\u00famero poligonales con k lados. Los siguientes son<\/p>\n<blockquote><p>\n   k=7  Heptagonal: 1, 7, 18, 34, 55,  81, 112, 148, 189, 235, &#8230;<br \/>\n   k=8  Octagonal:  1, 8, 21, 40, 65,  96, 133, 176, 225, 280, &#8230;<br \/>\n   k=9  Nonagonal:  1, 9, 24, 46, 75, 111, 154, 204, 261, 325, &#8230;\n<\/p><\/blockquote>\n<p>En la siguiente relaci\u00f3n de ejercicios (elaborada para <a href=\"http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m\">I1M<\/a>) se muestran distintas definiciones de los n\u00fameros poligonales y algunas de sus propiedades, como el teorema de Fermat, en Haskell.<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\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 1. Definir, por recursi\u00f3n, la funci\u00f3n \r\n--    poligonalR :: Integer -> Integer -> Integer\r\n-- tal que (poligonalR k n) es el n-\u00e9simo n\u00famero poligonal con k\r\n-- lados. Por ejemplo,\r\n--    [poligonalR 3 n | n <- [1..5]]  ==  [1,3,6,10,15]\r\n--    [poligonalR 4 n | n <- [1..5]]  ==  [1,4,9,16,25]\r\n--    [poligonalR 5 n | n <- [1..5]]  ==  [1,5,12,22,35]\r\n--    [poligonalR 6 n | n <- [1..5]]  ==  [1,6,15,28,45]\r\n-- ---------------------------------------------------------------------\r\n\r\npoligonalR :: Integer -> Integer -> Integer\r\npoligonalR _ 1 = 1\r\npoligonalR k n = (1+(k-2)*(n-1)) + poligonalR k (n-1)\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 2. Definir, por recursi\u00f3n, la funci\u00f3n \r\n--    poligonalC :: Integer -> Integer -> Integer\r\n-- tal que (poligonalC k n) es el n-\u00e9simo n\u00famero poligonal con k\r\n-- lados. Por ejemplo,\r\n--    [poligonalC 3 n | n <- [1..5]]  ==  [1,3,6,10,15]\r\n--    [poligonalC 4 n | n <- [1..5]]  ==  [1,4,9,16,25]\r\n--    [poligonalC 5 n | n <- [1..5]]  ==  [1,5,12,22,35]\r\n--    [poligonalC 6 n | n <- [1..5]]  ==  [1,6,15,28,45]\r\n-- ---------------------------------------------------------------------\r\n\r\npoligonalC :: Integer -> Integer -> Integer\r\npoligonalC k n =\r\n    sum [1+(k-2)*(m-1) | m <- [1..n]]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 3. A partir de la sucesi\u00f3n de los 5 primeros n\u00fameros\r\n-- poligonales, para k entre 3 y 9, conjeturar una f\u00f3rmula para calcular\r\n-- el n-\u00e9simo n\u00famero poligonal con k lados.\r\n-- ---------------------------------------------------------------------\r\n\r\n-- Usando Wolfram Alpha se obtienen las siguientes f\u00f3rmulas\r\n--    k=3   a(n) = n*(n+1)\/2       http:\/\/wolfr.am\/1b3qmaE\r\n--    k=4   a(n) = n^2             http:\/\/wolfr.am\/1fvqPlX\r\n--    k=5   a(n) = n*(3*n-1)\/2     http:\/\/wolfr.am\/1llp3uF\r\n--    k=6   a(n) = 2*n^2-n         http:\/\/wolfr.am\/1k5nYTD\r\n--    k=7   a(n) = (5*n^2-3*n)\/2   http:\/\/wolfr.am\/1aGSjrl\r\n--    k=8   a(n) = 3*n^2-2*n       http:\/\/wolfr.am\/1llppRM\r\n--    k=9   a(n) = (7*n^2-5*n)\/2   http:\/\/wolfr.am\/1k5oT6w\r\n-- En general,\r\n--          a(n) = ((k-2)*n^2-(k-4)*n)\/2 \r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 4. Comprobar con QuickCheck la f\u00f3rmula para calcular el\r\n-- n-\u00e9simo n\u00famero poligonal con k lados conjeturada en el ejercicio\r\n-- anterior. \r\n-- ---------------------------------------------------------------------\r\n\r\n-- La conjetura es\r\nprop_poligonal :: Integer -> Integer -> Property\r\nprop_poligonal k n =\r\n    k > 0 && n > 0 ==> poligonalR k n == ((k-2)*n^2-(k-4)*n) `div` 2\r\n    \r\n-- La comprobaci\u00f3n es\r\n--    ghci> quickCheck prop_poligonal\r\n--    +++ OK, passed 100 tests.\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 25. Definir, con la f\u00f3rmula de ejercicio anterior, la\r\n-- funci\u00f3n  \r\n--    poligonal :: Integer -> Integer -> Integer\r\n-- tal que (poligonal k n) es el n-\u00e9simo n\u00famero poligonal con k\r\n-- lados. Por ejemplo,\r\n--    [poligonal 3 n | n <- [1..5]]  ==  [1,3,6,10,15]\r\n--    [poligonal 4 n | n <- [1..5]]  ==  [1,4,9,16,25]\r\n--    [poligonal 5 n | n <- [1..5]]  ==  [1,5,12,22,35]\r\n--    [poligonal 6 n | n <- [1..5]]  ==  [1,6,15,28,45]\r\n-- ---------------------------------------------------------------------\r\n\r\npoligonal :: Integer -> Integer -> Integer\r\npoligonal k n = ((k-2)*n^2-(k-4)*n) `div` 2\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 6. Comprobar con QuickCheck que las tres definiciones de\r\n-- poligonal son equivalentes.\r\n-- ---------------------------------------------------------------------\r\n\r\n-- La propiedad es\r\nprop_equivalencia_poligonal :: Integer -> Integer -> Property\r\nprop_equivalencia_poligonal k n =\r\n    k > 0 && n > 0 ==> poligonalR k n == x &&\r\n                       poligonalC k n == x \r\n    where x = poligonal k n\r\n\r\n-- La comprobaci\u00f3n es\r\n--    ghci> quickCheck prop_equivalencia_poligonal\r\n--    +++ OK, passed 100 tests.\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 7. Comparar el tiempo y espacio utilizado en los\r\n-- siguientes c\u00e1lculos\r\n--    poligonalR 3 100000\r\n--    poligonalC 3 100000\r\n--    poligonal  3 100000\r\n-- ---------------------------------------------------------------------\r\n\r\n-- El c\u00e1lculo es\r\n--    ghci> :set +s\r\n--    ghci> poligonalR 3 100000\r\n--    5000050000\r\n--    (0.32 secs, 30522312 bytes)\r\n--    ghci> poligonalC 3 100000\r\n--    5000050000\r\n--    (0.30 secs, 28852176 bytes)\r\n--    ghci> poligonal 3 100000\r\n--    5000050000\r\n--    (0.00 secs, 519272 bytes)\r\n--    ghci> :unset +s\r\n\r\n-- ---------------------------------------------------------------------\r\n-- \u00a7 La sucesi\u00f3n de n\u00fameros poligonales                               --\r\n-- ---------------------------------------------------------------------\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 8. Definir, usando triangular, la funci\u00f3n\r\n--    poligonales1 :: Integer -> [Integer]\r\n-- tal que (poligonales1 k) es la lista de los n\u00fameros poligonales de k\r\n-- lados. Por ejemplo,  \r\n--    take 10 (poligonales1 3)  ==  [1,3,6,10,15,21,28,36,45,55]\r\n--    take 10 (poligonales1 4)  ==  [1,4,9,16,25,36,49,64,81,100]\r\n--    take 10 (poligonales1 5)  ==  [1,5,12,22,35,51,70,92,117,145]\r\n-- ---------------------------------------------------------------------\r\n\r\npoligonales1 :: Integer -> [Integer]\r\npoligonales1 k = [poligonal k n | n <- [1..]]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 9. Definir, usando poligonales1, la funci\u00f3n\r\n--   diferencias1 :: Integer -> [Integer]\r\n-- tal que (diferencias1 k) es la lista de las diferencias entre el\r\n-- n-\u00e9simo n\u00famero poligonal y su anterior, para n > 1. Por ejemplo,\r\n--    take 5 (diferencias1 3)  ==  [2,3,4,5,6]\r\n--    take 5 (diferencias1 4)  ==  [3,5,7,9,11]\r\n--    take 5 (diferencias1 5)  ==  [4,7,10,13,16]\r\n-- ---------------------------------------------------------------------\r\n\r\ndiferencias1 :: Integer -> [Integer]\r\ndiferencias1 k = zipWith (-) (tail xs) xs\r\n    where xs = poligonales1 k\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 10. Definir, por comprensi\u00f3n, la funci\u00f3n\r\n--   diferencias :: Integer -> [Integer]\r\n-- tal que (diferencias k) es la lista de las diferencias entre el\r\n-- n-\u00e9simo n\u00famero poligonal y su anterior, para n > 1. Por ejemplo,\r\n--    take 5 (diferencias 3)  ==  [2,3,4,5,6]\r\n--    take 5 (diferencias 4)  ==  [3,5,7,9,11]\r\n--    take 5 (diferencias 5)  ==  [4,7,10,13,16]\r\n-- ---------------------------------------------------------------------\r\n\r\ndiferencias :: Integer -> [Integer]\r\ndiferencias k = [k-1,2*k-3..]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 11. Definir, por recursi\u00f3n, la funci\u00f3n\r\n--    poligonales2 :: Integer -> [Integer]\r\n-- tal que (poligonales2 k) es la lista de los n\u00fameros poligonales de k\r\n-- lados. Por ejemplo, \r\n--    take 10 (poligonales2 3)  ==  [1,3,6,10,15,21,28,36,45,55]\r\n--    take 10 (poligonales2 4)  ==  [1,4,9,16,25,36,49,64,81,100]\r\n--    take 10 (poligonales2 5)  ==  [1,5,12,22,35,51,70,92,117,145]\r\n-- ---------------------------------------------------------------------\r\n\r\npoligonales2 :: Integer -> [Integer]\r\npoligonales2 k = 1 : zipWith (+) (diferencias k) (poligonales2 k)\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 12. Definir, usando scanl, la funci\u00f3n\r\n--    poligonales3 :: Integer -> [Integer]\r\n-- tal que (poligonales3 k) es la lista de los n\u00fameros poligonales de k\r\n-- lados. Por ejemplo, \r\n--    take 10 (poligonales3 3)  ==  [1,3,6,10,15,21,28,36,45,55]\r\n--    take 10 (poligonales3 4)  ==  [1,4,9,16,25,36,49,64,81,100]\r\n--    take 10 (poligonales3 5)  ==  [1,5,12,22,35,51,70,92,117,145]\r\n-- ---------------------------------------------------------------------\r\n\r\npoligonales3 :: Integer -> [Integer]\r\npoligonales3 k = scanl (+) 1 (diferencias k)\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 13. Definir la funci\u00f3n\r\n--    prop_equivalentes_poligonales :: Integer -> Int -> Bool\r\n-- tal que (prop_equivalentes_poligonales k n) se verifica si las tres\r\n-- definiciones de poligonales de k lados coinciden para todos los\r\n-- n\u00fameros entre 1 y n. \r\n--\r\n-- Comprobar si coinciden para los n\u00fameros entre 1 y 1000 y k entre 3 y\r\n-- 5. \r\n-- ---------------------------------------------------------------------\r\n\r\nprop_equivalentes_poligonales :: Integer -> Int -> Bool\r\nprop_equivalentes_poligonales k n =\r\n    take n (poligonales2 k) == xs && \r\n    take n (poligonales3 k) == xs\r\n    where xs = take n (poligonales1 k)\r\n\r\n-- La comprobaci\u00f3n  es\r\n--    ghci> prop_equivalentes_poligonales 1000\r\n--    True\r\n\r\n-- ---------------------------------------------------------------------\r\n-- \u00a7 Relaci\u00f3n entre n\u00fameros poligonales y triangulares                --\r\n-- ---------------------------------------------------------------------\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Nota 1. En lo que sigue usaremos la siguiente notaci\u00f3n\r\n--    P(k,n) es el n-\u00e9simo n\u00famero poligonal de k lados\r\n--    T(n)   es el n-\u00e9simo n\u00famero triangular.\r\n-- ---------------------------------------------------------------------\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 14. Definir la funci\u00f3n\r\n--    triangular :: Integer -> Integer\r\n-- tal que (triangular n) es el n-\u00e9simo n\u00famero triangular. Por ejemplo, \r\n--    [triangular n | n <- [1..5]]  ==  [1,3,6,10,15]\r\n-- ---------------------------------------------------------------------\r\n\r\ntriangular :: Integer -> Integer\r\ntriangular = poligonal 3\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 15. Comprobar con QuickCheck que\r\n--    P(k,n) = n + (k-2)T(n-1)\r\n-- ---------------------------------------------------------------------\r\n\r\n-- La propiedad es\r\nprop_poligonal_triangular1 :: Integer -> Integer -> Property\r\nprop_poligonal_triangular1 k n =\r\n    k > 0 && n > 0 ==>\r\n    poligonal k n == n + (k-2) * triangular (n-1)\r\n\r\n-- La comprobaci\u00f3n es\r\n--    ghci> quickCheck prop_poligonal_triangular1\r\n--    +++ OK, passed 100 tests.\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 16. Comprobar con QuickCheck que\r\n--    P(k+1,n) - P(k,n) = T(n-1)\r\n-- ---------------------------------------------------------------------\r\n\r\n-- La propiedad es\r\nprop_poligonal_triangular2 :: Integer -> Integer -> Property\r\nprop_poligonal_triangular2 k n =\r\n    k > 0 && n > 0 ==>\r\n    poligonal (k+1) n - poligonal k n == triangular (n-1)\r\n\r\n-- La comprobaci\u00f3n es\r\n--    ghci> quickCheck prop_poligonal_triangular2\r\n--    +++ OK, passed 100 tests.\r\n\r\n-- ---------------------------------------------------------------------\r\n-- \u00a7 Combinaciones de n\u00fameros poligonales                             --\r\n-- ---------------------------------------------------------------------\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 17. Definir la funci\u00f3n\r\n--    interseccion :: Ord a => [a] -> [a] -> [a]\r\n-- tal que (interseccion xs ys) es la intersecci\u00f3n de las dos listas,\r\n-- posiblemente infinitas, ordenadas de menor a mayor xs e ys. Por ejemplo,\r\n--    take 5 (interseccion [2,4..] [3,6..])  ==  [6,12,18,24,30]\r\n-- ---------------------------------------------------------------------\r\n\r\ninterseccion :: Ord a => [a] -> [a] -> [a]\r\ninterseccion [] _ = []\r\ninterseccion _ [] = []\r\ninterseccion (x:xs) (y:ys)\r\n    | x == y    = x : interseccion xs ys\r\n    | x < y     = interseccion (dropWhile (<y) xs) (y:ys)\r\n    | otherwise = interseccion (x:xs) (dropWhile (<x) ys)\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 18. Definir la funci\u00f3n\r\n--    poligonalesDobles :: Integer -> Integer -> [Integer]\r\n-- tal que (poligonalesDobles s t) es la lista de los n\u00fameros\r\n-- poligonales de s lados que tambi\u00e9n son poligonales de t lados. Por\r\n-- ejemplo, \r\n--    take 4 (poligonalesDobles 3 4)  ==  [1,36,1225,41616]\r\n--    take 4 (poligonalesDobles 3 5)  ==  [1,210,40755,7906276]\r\n--    take 4 (poligonalesDobles 3 6)  ==  [1,6,15,28]\r\n--    take 4 (poligonalesDobles 4 5)  ==  [1,9801,94109401,903638458801]\r\n--    take 4 (poligonalesDobles 4 6)  ==  [1,1225,1413721,1631432881]\r\n-- ---------------------------------------------------------------------\r\n\r\npoligonalesDobles :: Integer -> Integer -> [Integer]\r\npoligonalesDobles s t =\r\n    interseccion (poligonales3 s) (poligonales3 t)\r\n\r\n-- ---------------------------------------------------------------------\r\n-- \u00a7 Teorema de Fermat de n\u00fameros poligonales                         --\r\n-- ---------------------------------------------------------------------\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 19. Definir la funci\u00f3n \r\n--    sumas :: [Integer] -> Integer -> Integer -> [[Integer]]\r\n-- tal que (sumas xs m n) es la lista de las de listas crecientes de,\r\n-- como m\u00e1ximo, m elementos de la lista ordenada creciente xs cuya suma\r\n-- es n. Por ejemplo, \r\n--    ghci> sumas [1..9] 2 7\r\n--    [[1,6],[2,5],[3,4],[7]]\r\n--    ghci> sumas [1..9] 3 7\r\n--    [[1,1,5],[1,2,4],[1,3,3],[1,6],[2,2,3],[2,5],[3,4],[7]]\r\n-- ---------------------------------------------------------------------\r\n\r\nsumas :: [Integer] -> Integer -> Integer -> [[Integer]]\r\nsumas _  _ 0 = [[]]\r\nsumas [] _ _ = []\r\nsumas _  0 _ = []\r\nsumas (x:xs) m n\r\n    | x > n     = []\r\n    | otherwise = [x:ys | ys <- sumas (x:xs) (m-1) (n-x)] ++ \r\n                  sumas xs m n\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 20. Definir la funci\u00f3n\r\n--    descomposicionesPoligonales :: Integer -> Integer -> Integer -> [[Integer]]\r\n-- tal que (descomposicionesPoligonales k m n) es la lista crecientes de,\r\n-- como m\u00e1ximo m n\u00fameros poligonales de k lados, cuya suma es n. Por\r\n-- ejemplo, \r\n--    descomposicionesPoligonales 4 4 20  ==  [[1,1,9,9],[4,16]]\r\n--    descomposicionesPoligonales 4 2 20  ==  [[4,16]]\r\n-- ---------------------------------------------------------------------\r\n\r\ndescomposicionesPoligonales :: Integer -> Integer -> Integer -> [[Integer]]\r\ndescomposicionesPoligonales k m n = \r\n    sumas (takeWhile (<=n) (poligonales3 k)) m n\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 21. Definir \r\n--    gradoPoligonal :: Integer -> Integer -> Integer\r\n-- tal que (gradoPoligonal k n) es el menor cantidad de n\u00fameros\r\n-- poligonales de k lados cuya suma es n. Por ejemplo,\r\n--    gradoPoligonal 3 5  ==  3\r\n--    gradoPoligonal 3 7  ==  2\r\n--    gradoPoligonal 4 5  ==  2\r\n--    gradoPoligonal 4 7  ==  4\r\n-- ---------------------------------------------------------------------\r\n\r\ngradoPoligonal :: Integer -> Integer -> Integer\r\ngradoPoligonal k n = \r\n    minimum [m | m <- [1..n], \r\n                 not (null (descomposicionesPoligonales k m n))]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 22. Calcular el n\u00famero m\u00ednimo de sumandos para expresar\r\n-- cualquiera de los 20 primeros n\u00fameros naturales usando n\u00fameros\r\n-- poligonales de 3, 4 \u00f3 5 lados, respectivamente.\r\n-- ---------------------------------------------------------------------\r\n\r\n-- El c\u00e1lculo es\r\n--    ghci> [gradoPoligonal 3 n | n <- [1..20]]\r\n--    [1,2,1,2,3,1,2,3,2,1,2,2,2,3,1,2,3,2,3,2]\r\n--    ghci> [gradoPoligonal 4 n | n <- [1..20]]\r\n--    [1,2,3,1,2,3,4,2,1,2,3,3,2,3,4,1,2,2,3,2]\r\n--    ghci> [gradoPoligonal 5 n | n <- [1..20]]\r\n--    [1,2,3,4,1,2,3,4,5,2,3,1,2,3,3,4,2,3,4,4]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 23. A la vista del c\u00e1lculo del ejercicio anterior,\r\n-- conjeturar la menor cota superior del n\u00famero m\u00ednimo de sumandos para\r\n-- expresar cualquiera n\u00famero natural como suma de n\u00fameros poligonales\r\n-- de k lados y comprobar la conjetura con QuickCheck. \r\n-- ---------------------------------------------------------------------\r\n\r\n-- La conjetura es que todos los n\u00fameros naturales se pueden expresar\r\n-- como suma de k, o menos, n\u00fameros poligonales de k lados (no\r\n-- necesariamente distintos). \r\n\r\n-- La expresi\u00f3n de la conjetura\r\nprop_gradoPoligonal :: Integer -> Integer -> Property\r\nprop_gradoPoligonal k n =\r\n    n >= 0 && k > 2 ==> not (null (descomposicionesPoligonales k k n))\r\n\r\n-- La comprobaci\u00f3n es\r\n--    ghci> quickCheck prop_gradoPoligonal\r\n--    +++ OK, passed 100 tests.\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Nota 1. En 1796, el matem\u00e1tico y cient\u00edfico alem\u00e1n Carl Friedrich\r\n-- Gauss descubri\u00f3 que todo entero positivo puede representarse como la\r\n-- suma de un m\u00e1ximo de tres n\u00fameros triangulares, hecho que describi\u00f3\r\n-- en su diario con la misma palabra que usara Arqu\u00edmedes en su famoso\r\n-- descubrimiento: \"\u00a1Eureka! num= \u0394 + \u0394 + \u0394\". Posteriormente, Fermat la\r\n-- generaliz\u00f3 para todos los n\u00fameros poligonales.\r\n-- ---------------------------------------------------------------------\r\n<\/pre>\n<p><b>Fuente<\/b><\/p>\n<ul>\n<li>Wikipedia. <a href=\"http:\/\/bit.ly\/L7SRtU\">Polygonal number<\/a>.\n<li>Wikipedia. <a href=\"http:\/\/bit.ly\/1exiKeh\">Teorema del n\u00famero poligonal de Fermat<\/a>.\n<\/ul>\n<p><b>Destino<\/b><br \/>\nLa 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>Un n\u00famero poligonal es aquel que puede ser representado como puntos dispuestos en forma de pol\u00edgono regular, empezando por el 1. Los primeros n\u00fameros poligonales son los n\u00fameros triangulares, estos se forman a partir de tri\u00e1ngulos. Los siguientes son los n\u00fameros cuadrangulares Los siguientes son los n\u00fameros pentagonales Los n\u00fameros triangulares son 1, 3, 6,&#8230;<\/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":[221,1],"tags":[270,299,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\/4083"}],"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=4083"}],"version-history":[{"count":7,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/4083\/revisions"}],"predecessor-version":[{"id":4095,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/4083\/revisions\/4095"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/media?parent=4083"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/categories?post=4083"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/tags?post=4083"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}