{"id":6588,"date":"2019-03-27T07:03:34","date_gmt":"2019-03-27T06:03:34","guid":{"rendered":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/?p=6588"},"modified":"2019-03-29T07:04:21","modified_gmt":"2019-03-29T06:04:21","slug":"i1m2018-resolucion-de-una-ecuacion-con-factoriales-en-haskell","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/i1m2018-resolucion-de-una-ecuacion-con-factoriales-en-haskell\/","title":{"rendered":"I1M2018: Resoluci\u00f3n de una ecuaci\u00f3n con factoriales en Haskell"},"content":{"rendered":"<p>En la tercera parte de la clase de hoy del curso de <a href=\"http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m-18\">Inform\u00e1tica de 1\u00ba del Grado en Matem\u00e1ticas<\/a> se han explicado las soluciones de los ejercicios de la relaci\u00f3n 28, cuyo objetivo es resolver la ecuaci\u00f3n a! * b! = a! + b! + c!, donde a, b y c son n\u00fameros naturales.<\/p>\n<p>Los ejercicios, y sus soluciones, se muestran a continuaci\u00f3n.<br \/>\n<!--more--><\/p>\n<pre lang=\"haskell\">\n-- ---------------------------------------------------------------------\n-- Introducci\u00f3n                                                       --\n-- ---------------------------------------------------------------------\n\n-- El objetivo de esta relaci\u00f3n de ejercicios es resolver la ecuaci\u00f3n\n--    a! * b! = a! + b! + c!\n-- donde a, b y c son n\u00fameros naturales.\n\n-- ---------------------------------------------------------------------\n-- Importaci\u00f3n de librer\u00edas auxiliares                                --\n-- ---------------------------------------------------------------------\n\nimport Test.QuickCheck \n\n-- ---------------------------------------------------------------------\n-- Ejercicio 1. Definir la funci\u00f3n\n--    factorial :: Integer -> Integer\n-- tal que (factorial n) es el factorial de n. Por ejemplo,\n--    factorial 5  ==  120\n-- ---------------------------------------------------------------------\n\nfactorial :: Integer -> Integer\nfactorial n = product [1..n]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 2. Definir la constante\n--    factoriales :: [Integer]\n-- tal que factoriales es la lista de los factoriales de los n\u00fameros\n-- naturales. Por ejemplo,\n--    take 7 factoriales  ==  [1,1,2,6,24,120,720]\n-- ---------------------------------------------------------------------\n\n-- 1\u00aa definici\u00f3n\nfactoriales1 :: [Integer]\nfactoriales1 = [factorial n | n <- [0..]]\n\n-- 2\u00aa definici\u00f3n\nfactoriales2 :: [Integer]\nfactoriales2 = scanl (*) 1 [1..]\n \n-- Comparaci\u00f3n de eficiencia:\n--    ghci> let n = factoriales !! 30000 in n-n\n--    0\n--    (3.20 secs, 723071452 bytes)\n--    ghci> let n = factoriales2 !! 30000 in n-n\n--    0\n--    (3.16 secs, 721944872 bytes)\n--    ghci> let n = factoriales3 !! 30000 in n-n\n--    0\n--    (1.74 secs, 720384724 bytes)\n\n-- Usaremos como factoriales la 2\u00aa definici\u00f3n:\nfactoriales :: [Integer]\nfactoriales = factoriales2\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 3. Definir, usando factoriales, la funci\u00f3n\n--    esFactorial :: Integer -> Bool\n-- tal que (esFactorial n) se verifica si existe un  n\u00famero natural m\n-- tal que n es m!. Por ejemplo,\n--    esFactorial 120  ==  True\n--    esFactorial  20  ==  False\n-- ---------------------------------------------------------------------\n\nesFactorial :: Integer -> Bool\nesFactorial n = n == head (dropWhile (<n) factoriales)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 4. Definir la constante\n--    posicionesFactoriales :: [(Integer,Integer)]\n-- tal que posicionesFactoriales es la lista de los factoriales con su\n-- posici\u00f3n. Por ejemplo,\n--    ghci> take 7 posicionesFactoriales\n--    [(0,1),(1,1),(2,2),(3,6),(4,24),(5,120),(6,720)]\n-- ---------------------------------------------------------------------\n\nposicionesFactoriales :: [(Integer,Integer)]\nposicionesFactoriales = zip [0..] factoriales \n\n-- ---------------------------------------------------------------------\n-- Ejercicio 5. Definir la funci\u00f3n\n--    invFactorial :: Integer -> Maybe Integer\n-- tal que (invFactorial x) es (Just n) si el factorial de n es x y es\n-- Nothing, en caso contrario. Por ejemplo,\n--    invFactorial 120  == Just 5\n--    invFactorial 20   == Nothing\n-- ---------------------------------------------------------------------\n\ninvFactorial :: Integer -> Maybe Integer\ninvFactorial x \n    | esFactorial x = Just (head [n | (n,y) <- posicionesFactoriales, y==x])\n    | otherwise     = Nothing\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 6. Definir la constante\n--    pares :: [(Integer,Integer)]\n-- tal que pares es la lista de todos los pares de n\u00fameros naturales. Por\n-- ejemplo, \n--    ghci> take 11 pares\n--    [(0,0),(0,1),(1,1),(0,2),(1,2),(2,2),(0,3),(1,3),(2,3),(3,3),(0,4)]\n-- ---------------------------------------------------------------------\n\npares :: [(Integer,Integer)]\npares = [(x,y) | y <- [0..], x <- [0..y]]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 7. Definir la constante\n--    solucionFactoriales :: (Integer,Integer,Integer)\n-- tal que solucionFactoriales es una terna (a,b,c) que es una soluci\u00f3n\n-- de la ecuaci\u00f3n \n--    a! * b! = a! + b! + c!\n-- Calcular el valor de solucionFactoriales.\n-- ---------------------------------------------------------------------\n\nsolucionFactoriales :: (Integer,Integer,Integer)\nsolucionFactoriales = (a,b,c)\n    where (a,b)  = head [(x,y) | (x,y) <- pares,\n                                 esFactorial (f x * f y - f x - f y)]\n          f      = factorial \n          Just c = invFactorial (f a * f b - f a - f b)\n\n-- El c\u00e1lculo es\n--    ghci> solucionFactoriales\n--    (3,3,4)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 8. Comprobar con QuickCheck que solucionFactoriales es la\n-- \u00fanica soluci\u00f3n de la ecuaci\u00f3n\n--    a! * b! = a! + b! + c!\n-- con a, b y c n\u00fameros naturales\n-- ---------------------------------------------------------------------\n\nprop_solucionFactoriales :: Integer -> Integer -> Integer -> Property\nprop_solucionFactoriales x y z =\n    x >= 0 && y >= 0 && z >= 0 \n    ==> (x,y,z) == solucionFactoriales || \n        not (f x * f y == f x + f y + f z)\n    where f = factorial\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_solucionFactoriales\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Nota: El ejercicio se basa en el art\u00edculo \"Ecuaci\u00f3n con factoriales\"\n-- del blog Gaussianos publicado en\n--    http:\/\/gaussianos.com\/ecuacion-con-factoriales\n-- ---------------------------------------------------------------------\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>En la tercera parte de la clase de hoy del curso de Inform\u00e1tica de 1\u00ba del Grado en Matem\u00e1ticas se han explicado las soluciones de los ejercicios de la relaci\u00f3n 28, cuyo objetivo es resolver la ecuaci\u00f3n a! * b! = a! + b! + c!, donde a, b y c son n\u00fameros naturales. Los&#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":[320],"tags":[],"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\/6588"}],"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=6588"}],"version-history":[{"count":1,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/6588\/revisions"}],"predecessor-version":[{"id":6589,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/6588\/revisions\/6589"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/media?parent=6588"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/categories?post=6588"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/tags?post=6588"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}