{"id":7142,"date":"2022-07-19T06:00:00","date_gmt":"2022-07-19T04:00:00","guid":{"rendered":"http:\/\/www.glc.us.es\/~jalonso\/exercitium\/?p=7142"},"modified":"2022-07-12T16:03:49","modified_gmt":"2022-07-12T14:03:49","slug":"sumas-alternas-de-factoriales","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/sumas-alternas-de-factoriales\/","title":{"rendered":"Sumas alternas de factoriales"},"content":{"rendered":"<p>Las primeras sumas alternas de los factoriales son n\u00fameros primos; en efecto,<\/p>\n<pre lang=\"text\">\n   3! - 2! + 1! = 5\n   4! - 3! + 2! - 1! = 19\n   5! - 4! + 3! - 2! + 1! = 101\n   6! - 5! + 4! - 3! + 2! - 1! = 619\n   7! - 6! + 5! - 4! + 3! - 2! + 1! = 4421\n   8! - 7! + 6! - 5! + 4! - 3! + 2! - 1! = 35899\n<\/pre>\n<p>son primos, pero<\/p>\n<pre lang=\"text\">\n   9! - 8! + 7! - 6! + 5! - 4! + 3! - 2! + 1! = 326981\n<\/pre>\n<p>no es primo.<\/p>\n<p>Definir las funciones<\/p>\n<pre lang=\"text\">\n   sumaAlterna         :: Integer -> Integer\n   sumasAlternas       :: [Integer]\n   conSumaAlternaPrima :: [Integer]\n<\/pre>\n<p>tales que<\/p>\n<ul>\n<li>(sumaAlterna n) es la suma alterna de los factoriales desde n hasta 1. Por ejemplo,<\/li>\n<\/ul>\n<pre lang=\"text\">\n     sumaAlterna 3  ==  5\n     sumaAlterna 4  ==  19\n     sumaAlterna 5  ==  101\n     sumaAlterna 6  ==  619\n     sumaAlterna 7  ==  4421\n     sumaAlterna 8  ==  35899\n     sumaAlterna 9  ==  326981\n     sumaAlterna (5*10^4) `mod` (10^6) == 577019\n<\/pre>\n<ul>\n<li>sumasAlternas es la sucesi\u00f3n de las sumas alternas de factoriales. Por ejemplo, <\/li>\n<\/ul>\n<pre lang=\"text\">\n     \u03bb> take 10 sumasAlternas1\n     [0,1,1,5,19,101,619,4421,35899,326981]\n<\/pre>\n<ul>\n<li>conSumaAlternaPrima es la sucesi\u00f3n de los n\u00fameros cuya suma alterna de factoriales es prima. Por ejemplo, <\/li>\n<\/ul>\n<pre lang=\"text\">\n     \u03bb> take 8 conSumaAlternaPrima\n     [3,4,5,6,7,8,10,15]\n<\/pre>\n<h4>Soluciones<\/h4>\n<pre lang=\"haskell\">\nimport Data.List (genericTake)\nimport Data.Numbers.Primes (isPrime)\nimport Test.QuickCheck\n\n-- 1\u00aa definici\u00f3n de sumaAlterna\n-- ============================\n\nsumaAlterna1 :: Integer -> Integer\nsumaAlterna1 1 = 1\nsumaAlterna1 n = factorial n - sumaAlterna1 (n-1)\n\nfactorial :: Integer -> Integer\nfactorial n = product [1..n]\n\n-- 2\u00aa definici\u00f3n de sumaAlterna\n-- ============================\n\nsumaAlterna2 :: Integer -> Integer\nsumaAlterna2 n =\n  sum (genericTake n (zipWith (*) signos (tail factoriales)))\n  where\n    signos | odd n     = concat (repeat [1,-1])\n           | otherwise = concat (repeat [-1,1])\n\n-- factoriales es la lista de los factoriales. Por ejemplo,\n--    take 7 factoriales  ==  [1,1,2,6,24,120,720]\nfactoriales :: [Integer]\nfactoriales = 1 : scanl1 (*) [1..]\n\n-- 3\u00aa definici\u00f3n de sumaAlterna\n-- ============================\n\nsumaAlterna3 :: Integer -> Integer\nsumaAlterna3 n = \n  sum (genericTake n (zipWith (*) signos (tail factoriales)))\n  where signos | odd n     = cycle [1,-1]\n               | otherwise = cycle [-1,1]\n\n-- 3\u00aa definici\u00f3n de sumaAlterna\n-- ============================\n\nsumaAlterna4 :: Integer -> Integer\nsumaAlterna4 n =\n  foldl (flip (-)) 0 (scanl1 (*) [1..n])\n\n-- Comprobaci\u00f3n de equivalencia de sumaAlterna\n-- ===========================================\n\n-- La propiedad es\nprop_sumaAlterna :: Positive Integer -> Bool \nprop_sumaAlterna (Positive n) =\n  all (== sumaAlterna1 n)\n      [sumaAlterna2 n,\n       sumaAlterna3 n,\n       sumaAlterna4 n]\n\n-- La comprobaci\u00f3n es\n--    \u03bb> quickCheck prop_sumaAlterna\n--    +++ OK, passed 100 tests.\n\n-- Comparaci\u00f3n de eficiencia de sumaAlterna \n-- ========================================\n\n-- La comparaci\u00f3n es\n--    \u03bb> sumaAlterna1 4000 `mod` (10^6)\n--    577019\n--    (6.21 secs, 16,154,113,192 bytes)\n--    \u03bb> sumaAlterna2 4000 `mod` (10^6)\n--    577019\n--    (0.01 secs, 24,844,664 bytes)\n--    \n--    \u03bb> sumaAlterna2 (5*10^4) `mod` (10^6)\n--    577019\n--    (1.81 secs, 4,729,583,864 bytes)\n--    \u03bb> sumaAlterna3 (5*10^4) `mod` (10^6)\n--    577019\n--    (0.89 secs, 4,725,983,928 bytes)\n--    \u03bb> sumaAlterna4 (5*10^4) `mod` (10^6)\n--    577019\n--    (0.70 secs, 4,710,770,592 bytes)\n\n-- En lo que sigue se usa la 3\u00aa definici\u00f3n\nsumaAlterna :: Integer -> Integer\nsumaAlterna = sumaAlterna3\n\n-- 1\u00aa definici\u00f3n de sumasAlternas\n-- ==============================\n\nsumasAlternas1 :: [Integer]\nsumasAlternas1 =\n  map sumaAlterna [0..]\n\n-- 2\u00aa definici\u00f3n de sumasAlternas\n-- ==============================\n\nsumasAlternas2 :: [Integer]\nsumasAlternas2 =\n  0 : zipWith (-) (tail factoriales) sumasAlternas2\n\n-- 3\u00aa definici\u00f3n de sumasAlternas\n-- ==============================\n\nsumasAlternas3 :: [Integer]\nsumasAlternas3 =\n  scanl (flip (-)) 0 $ scanl1 (*) [1..]\n\n-- Comprobaci\u00f3n de equivalencia\n-- ============================\n\n-- La propiedad es\nprop_sumasAlternas :: NonNegative Int -> Bool\nprop_sumasAlternas (NonNegative n) =\n  all (== sumasAlternas1 !! n)\n      [sumasAlternas2 !! n,\n       sumasAlternas3 !! n]\n  \n-- La comprobaci\u00f3n es\n--    \u03bb> quickCheck prop_sumasAlternas\n--    +++ OK, passed 100 tests.\n\n-- Comparaci\u00f3n de eficiencia\n-- =========================\n\n-- La comparaci\u00f3n es\n--    \u03bb> length (show (sumasAlternas1 !! (5*10^4)))\n--    213237\n--    (4.90 secs, 4,731,620,600 bytes)\n--    \u03bb> length (show (sumasAlternas2 !! (5*10^4)))\n--    213237\n--    (2.39 secs, 4,726,820,456 bytes)\n--    \u03bb> length (show (sumasAlternas3 !! (5*10^4)))\n--    213237\n--    (1.78 secs, 4,726,820,280 bytes)\n\n-- 1\u00aa definici\u00f3n de conSumaAlternaPrima\n-- ====================================\n\nconSumaAlternaPrima1 :: [Integer]\nconSumaAlternaPrima1 =\n  [n | n <- [0..], isPrime (sumaAlterna n)]\n\n-- 2\u00aa definici\u00f3n de conSumaAlternaPrima\n-- ====================================\n\nconSumaAlternaPrima2 :: [Integer]\nconSumaAlternaPrima2 =\n  [x | (x,y) <- zip [0..] sumasAlternas2, isPrime y]\n\n-- 3\u00aa definici\u00f3n de conSumaAlternaPrima\n-- ====================================\n\nconSumaAlternaPrima3 :: [Integer]\nconSumaAlternaPrima3 =\n  filter (isPrime . sumaAlterna) [0..]\n\n-- Comprobaci\u00f3n de equivalencia de conSumaAlternaPrima\n-- ===================================================\n\n-- La propiedad es\nprop_conSumaAlternaPrima :: NonNegative Int -> Bool\nprop_conSumaAlternaPrima (NonNegative n) =\n  all (== conSumaAlternaPrima1 !! n)\n      [conSumaAlternaPrima2 !! n,\n       conSumaAlternaPrima3 !! n]\n\n-- La comprobaci\u00f3n es\n--    \u03bb> quickCheckWith (stdArgs {maxSize=5}) prop_conSumaAlternaPrima\n--    +++ OK, passed 100 tests.\n<\/pre>\n<p>El c\u00f3digo se encuentra en <a href=\"https:\/\/github.com\/jaalonso\/Exercitium\/blob\/main\/src\/Suma_alterna_de_factoriales.hs\">GitHub<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Las primeras sumas alternas de los factoriales son n\u00fameros primos; en efecto, 3! &#8211; 2! + 1! = 5 4! &#8211; 3! + 2! &#8211; 1! = 19 5! &#8211; 4! + 3! &#8211; 2! + 1! = 101 6! &#8211; 5! + 4! &#8211; 3! + 2! &#8211; 1! = 619 7! &#8211; 6!&#8230;<\/p>\n","protected":false},"author":1,"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":[2],"tags":[521],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/7142"}],"collection":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/comments?post=7142"}],"version-history":[{"count":1,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/7142\/revisions"}],"predecessor-version":[{"id":7143,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/7142\/revisions\/7143"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/media?parent=7142"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/categories?post=7142"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/tags?post=7142"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}