{"id":3817,"date":"2013-11-14T09:03:09","date_gmt":"2013-11-14T08:03:09","guid":{"rendered":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/?p=3817"},"modified":"2016-01-09T18:47:24","modified_gmt":"2016-01-09T17:47:24","slug":"sucesion-con-radicales-en-haskell","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/sucesion-con-radicales-en-haskell\/","title":{"rendered":"Sucesi\u00f3n con radicales en Haskell"},"content":{"rendered":"<p>Uno de los problemas de las Olimpiadas matem\u00e1ticas de este a\u00f1o es el siguiente<\/p>\n<blockquote><p>\nDada la sucesi\u00f3n, definida por<br \/>\n<img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=x_0+%3D+1&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"x_0 = 1\" class=\"latex\" \/><br \/>\n<img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=x_%7Bn%2B1%7D+%3D+2x_n%2B%5Csqrt%7B3x_n%5E2+-2%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"x_{n+1} = 2x_n+&#92;sqrt{3x_n^2 -2}\" class=\"latex\" \/>,<br \/>\ncalcular el t\u00e9rmino 2013 de la misma.\n<\/p><\/blockquote>\n<p>A partir del problema he elaborado, con la colaboraci\u00f3n de <a href=\"http:\/\/www.cs.us.es\/~mjoseh\/\">Mar\u00eda J. Hidalgo<\/a>, la siguiente relaci\u00f3n de ejercicios en 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>.<\/p>\n<p>En la relaci\u00f3n se presenta 5 definiciones distintas de la sucesi\u00f3n:<\/p>\n<ul>\n<li>la primera es traducci\u00f3n directa usando n\u00fameros flotantes con doble precisi\u00f3n,\n<li>la segunda es una adaptaci\u00f3n de la anterior usando n\u00fameros enteros,\n<li>la tercera es una definici\u00f3n sin radicales basada en propiedades de la sucesi\u00f3n conjeturadas usando la segunda definici\u00f3n,\n<li>la cuarta es una versi\u00f3n con memoria de la anterior y\n<li>la quinta es una traducci\u00f3n directa usando <a href=\"http:\/\/es.wikipedia.org\/wiki\/N\u00famero_construible\">n\u00fameros construibles<\/a> mediante la librer\u00eda  <a href=\"http:\/\/hackage.haskell.org\/package\/constructible-0.1.0.1\/docs\/Data-Real-Constructible.html\">Data.Real.Constructible<\/a>.\n<\/ul>\n<p>Se observa que las dos primeras definiciones son incorrectas (debido a errores de redondeo), la tercera es correcta pero basada en propiedades no evidentes y adem\u00e1s es ineficiente, la cuarta es m\u00e1s eficiente y la quinta es correcta, elemental y eficiente.<\/p>\n<p>La relaci\u00f3n de ejercicios, y sus soluciones, es la siguiente<br \/>\n<!--more--><\/p>\n<pre lang=\"haskell\">\n-- ---------------------------------------------------------------------\n-- \u00a7 Librer\u00edas auxiliares                                             --\n-- ---------------------------------------------------------------------\n\nimport Data.Real.Constructible\n\n-- ---------------------------------------------------------------------\n-- \u00a7 Primera definici\u00f3n                                               --\n-- ---------------------------------------------------------------------\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 1. Definir la funci\u00f3n\n--    suc1 :: Double -> Double\n-- tal que (suc1 n) es el n-\u00e9simo t\u00e9rmino de la sucesi\u00f3n x(n) tal que \n--    x(0) = 1\n--    x(n+1) = 2*x(n)+sqrt(3*x(n)^2 -2)\n-- Por ejemplo,\n--    suc1 9  ==  110771.0\n-- ---------------------------------------------------------------------\n\nsuc1 :: Double -> Double\nsuc1 0 = 1\nsuc1 n = 2*y + sqrt(3*y^2-2)\n    where y = suc1 (n-1)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 2. Calcular los 10 primeros t\u00e9rminos de la sucesi\u00f3n suc1. \n-- \u00bfQu\u00e9 se observa?\n-- ---------------------------------------------------------------------\n\n-- El c\u00e1lculo es\n--    ghci> [suc1 n | n <- [0..9]]\n--    [1.0,3.0,11.0,41.0,153.0,571.0,2131.0,7953.0,29681.0,110771.0]\n--\n-- Se observa que son n\u00fameros enteros.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 3. Calcular el valor de (suc1 n) para n entre 270 y 279. \n-- \u00bfQu\u00e9 se observa?\n-- ---------------------------------------------------------------------\n\n-- El c\u00e1lculo es\n--    ghci> [suc1 n | n <- [269..272]]\n--    [5.6336314869343334e153,2.1024998940358734e154,Infinity,Infinity]\n--\n-- Se observa que, a partir de n=271, el valor de (suc1 n) es Infinity .  \n\n-- ---------------------------------------------------------------------\n-- \u00a7 Segunda definici\u00f3n                                               --\n-- ---------------------------------------------------------------------\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 4. Definir la funci\u00f3n\n--    suc2 :: Int -> Integer\n-- tal que (suc2 n) es el n-\u00e9simo t\u00e9rmino de la sucesi\u00f3n x(n) tal que \n--    x(0) = 1\n--    x(n+1) = 2*x(n)+sqrt(3*x(n)^2 -2)\n-- Por ejemplo,\n--    suc2 9  ==  110771\n-- ---------------------------------------------------------------------\n\nsuc2 :: Int -> Integer\nsuc2 0 = 1\nsuc2 n = 2*floor y + floor (sqrt(3*y^2-2))\n    where y = fromIntegral (suc2 (n-1))\n              \n-- ---------------------------------------------------------------------\n-- Ejercicio 5. Calcular los 10 primeros t\u00e9rminos de la sucesi\u00f3n suc2. \n-- \u00bfQu\u00e9 se observa?\n-- ---------------------------------------------------------------------\n\n-- El c\u00e1lculo es\n--    ghci> [suc2 n | n <- [0..9]]\n--    [1,3,11,41,153,571,2131,7953,29681,110771]\n--\n-- Se observa que coincide con los de suc1.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 6. Calcular el valor de (suc1 271) y (suc2 271) \u00bfQu\u00e9 se\n-- observa? \n-- ---------------------------------------------------------------------\n\n-- El c\u00e1lculo es\n--    ghci> suc1 271\n--    Infinity\n--    ghci> suc2 271\n--    179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474166427765774142334213821161990973990483643290782815647878226598877573710485167378404229346650077465677328722295309879585030541721400976037074083503612624896\n--\n-- Se observa que los valores son distintos. \n\n-- ---------------------------------------------------------------------\n-- Ejercicio 7. Calcular el valor de (suc2 2013) \u00bfEs seguro que el valor\n-- es correcto?\n-- ---------------------------------------------------------------------\n\n-- El c\u00e1lculo\n--    ghci> suc2 2013\n--    539307940458694772318791557236707420085393093682691971820290243473198027416502889398125431967222608063360341639614180072976369306443249867478542291918422373133303680274596455828906658803738282358359248856255017306514452047027388644421739331622481711490051532053758894719841737815439148914506068988872672411648\n-- \n-- No es seguro que el valor sea correcto porque se usa operaciones\n-- aproximadas como sqrt cuyo tipo es\n--    sqrt :: Floating a => a -> a\n\n-- ---------------------------------------------------------------------\n-- \u00a7 Tercera definici\u00f3n                                               --\n-- ---------------------------------------------------------------------\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 8. Definir la funci\u00f3n\n--    adyacentes :: [a] -> [(a,a)]\n-- tal que (adyacentes xs) es la lista de elementos adyacentes en la\n-- lista xs. Por ejemplo,\n--    adyacentes [3,2,5,1]  ==  [(3,2),(2,5),(5,1)]\n-- ---------------------------------------------------------------------\n\nadyacentes :: [a] -> [(a,a)]\nadyacentes xs = zip xs (tail xs)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 9. Definir la constante\n--    pares :: [(Integer,Integer)]\n-- cuyo valor es la lista de pares de elementos de suc2. Por ejemplo,\n--    take 5 pares  ==  [(3,11),(11,41),(41,153),(153,571),(571,2131)]\n-- ---------------------------------------------------------------------\n\npares :: [(Integer,Integer)]\npares = adyacentes [suc2 n | n <- [1..]] \n\n-- ---------------------------------------------------------------------\n-- Ejercicio 10. Definir la constante\n--    cocientes :: [Integer]\n-- cuyo valor es la lista de los cocientes entre (suc2 n) y (suc2 n-1)\n-- Calcular los 10 primeros cocientes. \u00bfQu\u00e9 se observa?\n-- ---------------------------------------------------------------------\n\ncocientes :: [Integer]\ncocientes = [y `div` x | (x,y) <- pares]\n\n-- El c\u00e1lculo es \n--    ghci> take 10 cocientes\n--    [3,3,3,3,3,3,3,3,3,3]\n-- \n-- Se observa que todos los cocientes son iguales a 3.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 11. Definir las constantes\n--    restos      :: [Integer]\n--    diferencias :: [Integer]\n-- cuyos valores son las listas de los restos entre (suc2 n) y (suc2 n-1)\n-- y las diferencias entre (suc2 n) y (suc2 n-1). Calcular los 10\n-- primeros restos y las 10 primeras diferencias. \u00bfQu\u00e9 se observa?\n-- ---------------------------------------------------------------------\n\nrestos :: [Integer]\nrestos = [y `rem` x | (x,y) <- pares]\n\ndiferencias :: [Integer]\ndiferencias = [y - x | (x,y) <- pares]\n\n-- El c\u00e1lculo es \n--    ghci> take 10 restos\n--    [2,8,30,112,418,1560,5822,21728,81090,302632]\n--    ghci> take 10 diferencias\n--    [8,30,112,418,1560,5822,21728,81090,302632,1129438]\n-- \n-- Se observa que (tail restos) = diferencias; es decir, si n > 1,\n-- entonces el resto de dividir x(n) entre x(n-1) es igual a x(n-1)\n-- menos x(n-2).\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 12. A partir de los ejercicios anteriores, redefinir la\n-- sucesi\u00f3n x(n) sin usar ra\u00edces cuadradas.\n-- ---------------------------------------------------------------------\n\n-- Por el ejercicio 10, el cociente entero de x(n) entre x(n-1) es 3 y,\n-- por el ejercicio 11, el resto es x(n-1) menos x(n-1). Por tanto,\n-- si n > 1 se tiene\n--    x(n) = 3*x(n-1) + (x(n-1) - x(n-2)) \n--         = 4*x(n-1) - x(n-2)\n-- Adem\u00e1s,\n--    x(0) = 1\n--    x(1) = 3\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 13. Definir la funci\u00f3n\n--    suc3 :: Int -> Integer\n-- tal que (suc3 n) es el n-\u00e9simo t\u00e9rmino de la sucesi\u00f3n calculado a\n-- partir de las relaciones del ejercicio anterior.\n-- ---------------------------------------------------------------------\n\nsuc3 :: Int -> Integer\nsuc3 0 = 1\nsuc3 1 = 3\nsuc3 n = 4 * suc3 (n-1) - suc3 (n-2)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 14. Calcular el primer n\u00famero n tal que (suc2 n) y (suc3 n)\n-- son distintos.\n-- ---------------------------------------------------------------------\n\n-- El c\u00e1lculo es\n--    ghci> head [n | n <- [0..], suc2 n \/= suc3 n ]\n--    29\n-- \n-- En efecto,\n--    ghci> suc2 29\n--    30435260762459852\n--    ghci> suc3 29\n--    30435260762459851\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 15. Calcular las estad\u00edsticas para calcular (suc3 30).\n-- ---------------------------------------------------------------------\n\n-- El c\u00e1lculo es\n--    ghci> :set +s \n--    ghci> suc3 30\n--    113585939507107651\n--    (10.58 secs, 308573992 bytes)\n\n-- ---------------------------------------------------------------------\n-- \u00a7 Cuarta definici\u00f3n                                                --\n-- ---------------------------------------------------------------------\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 16. Definir, con memorizaci\u00f3n, la constante\n--    terminosSuc4 :: [Integer]\n-- cuyo valor es la lista de los t\u00e9rminos de la sucesi\u00f3n- Por ejemplo,\n--    ghci> take 10 terminosSuc4\n--    [1,3,11,41,153,571,2131,7953,29681,110771]\n-- ---------------------------------------------------------------------\n\nterminosSuc4 :: [Integer]\nterminosSuc4 = 1 : 3 : zipWith f terminosSuc4 (tail terminosSuc4)\n    where f a b = 4*b-a\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 17. Definir, usando el ejercicio anterior, la funci\u00f3n\n--    suc4 :: Int -> Integer\n-- tal que (suc4 n) es el n-\u00e9simo t\u00e9rmino de la sucesi\u00f3n. Por ejemplo,\n--    suc4 9  ==  110771\n-- ---------------------------------------------------------------------\n\nsuc4 :: Int -> Integer\nsuc4 n = terminosSuc4 !! n\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 18. Calcular las estad\u00edsticas para calcular (suc4 30).\n-- ---------------------------------------------------------------------\n\n-- El c\u00e1lculo es\n--    ghci> suc4 30\n--    113585939507107651\n--    (0.01 secs, 514024 bytes)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 19. Calcular el valor (suc4 2013) y compararlo con\n-- (suc2 2013) calculada en el ejercicio 7. \u00bfQu\u00e9 se observa?\n-- ---------------------------------------------------------------------\n\n-- El c\u00e1lculo es\n--    ghci> suc6 2013\n--    168776250022825386299444353956146044460247790742873687582016133344522778834838119356347990774063576046090482033035139781143578827887856444672702026046129704662452685502970573398959704390641212469508877669676385079967305749285619309371243721828379393663082046352880287021533203235565273595398911918334776813716437912906145378621573160747223490630284199813949162867666143722222198554542704883958146656862955220278405352456921674979356418306447479925189466207568278514262313094775498075311079939520159895669319197545406726501442522056327512294217936777501198964667044981645594285486625037252918910100964709474363205640133571220174702869751355440184294783274959230759397713358696912162786998522539605439904172284196408952804589968814256644505539555966788601728476250422330377288011399953887869866071982694327789456353900043868106892040957784702635555737001663424349147133198274906620670361879190816303348127152538837067889974857620282804630592816383493496381502850806685327131505567094035597112342874567493562447260405834933418947862442299950353801786735106018538806097833792417294595444154254566097806788362345007575154748269209956755993320683892467446091\n--\n-- Se observa que el resultado es distinto.\n\n-- ---------------------------------------------------------------------\n-- \u00a7 Quinta definici\u00f3n                                                --\n-- ---------------------------------------------------------------------\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 20. Definir, usando la librer\u00eda Data.Real.Constructible, la\n-- funci\u00f3n \n--    suc5 :: Integer -> Construct\n-- tal que (suc5 n) es el n-\u00e9simo t\u00e9rmino de la sucesi\u00f3n. Por ejemplo, \n--    suc5 9  ==  110771\n-- --------------------------------------------------------------------- \n\nsuc5:: Integer -> Construct\nsuc5 0 = 1\nsuc5 n = 2*y + sqrt(3*y^2-2)\n    where y = suc5 (n-1)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 21. Comprobar que (suc5 2013) y (suc4 2013) son iguales.\n-- ---------------------------------------------------------------------\n\n-- La comprobaci\u00f3n es\n--    ghci> fromIntegral (suc4 2013) == fromConstruct (suc5 2013)\n--    True\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Uno de los problemas de las Olimpiadas matem\u00e1ticas de este a\u00f1o es el siguiente Dada la sucesi\u00f3n, definida por , calcular el t\u00e9rmino 2013 de la misma. A partir del problema he elaborado, con la colaboraci\u00f3n de Mar\u00eda J. Hidalgo, la siguiente relaci\u00f3n de ejercicios en Haskell para la asignatura de Inform\u00e1tica (de 1\u00ba del&#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":[1],"tags":[270,299],"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\/3817"}],"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=3817"}],"version-history":[{"count":4,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/3817\/revisions"}],"predecessor-version":[{"id":5275,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/3817\/revisions\/5275"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/media?parent=3817"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/categories?post=3817"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/tags?post=3817"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}