{"id":7034,"date":"2022-05-23T12:54:43","date_gmt":"2022-05-23T10:54:43","guid":{"rendered":"http:\/\/www.glc.us.es\/~jalonso\/exercitium\/?p=7034"},"modified":"2022-05-23T13:01:34","modified_gmt":"2022-05-23T11:01:34","slug":"densidades-de-numeros-abundantes-perfectos-y-deficientes","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/densidades-de-numeros-abundantes-perfectos-y-deficientes\/","title":{"rendered":"Densidades de n\u00fameros abundantes, perfectos y deficientes"},"content":{"rendered":"<p>La n-\u00e9sima densidad de un tipo de n\u00famero es el cociente entre la cantidad de los n\u00fameros entre 1 y n que son del tipo considerado y n. Por ejemplo, la 7-\u00e9sima densidad de los m\u00faltiplos de 3 es 2\/7 ya que entre los 7 primeros n\u00fameros s\u00f3lo 2 son m\u00faltiplos de 3.<\/p>\n<p>Definir las funciones<\/p>\n<pre lang=\"text\">\n   densidades :: Int -> (Double,Double,Double)\n   graficas   :: Int -> IO ()\n<\/pre>\n<p>tales que<\/p>\n<ul>\n<li><code>(densidades n)<\/code> es la terna formada por la n-\u00e9sima densidad\n<ul>\n<li>de los n\u00fameros <a href=\"http:\/\/bit.ly\/1BniqiY\">abundantes<\/a> (es decir, para los que la suma de sus divisores propios es mayor que el n\u00famero), <\/li>\n<li>de los n\u00fameros <a href=\"http:\/\/bit.ly\/1BniShk\">perfectos<\/a> (es decir, para los que la suma de sus divisores propios es mayor que el n\u00famero) y <\/li>\n<li>de los n\u00fameros <a href=\"http:\/\/bit.ly\/1BniQ9h\">deficientes<\/a> (es decir, para los que la suma de sus divisores propios es menor que el n\u00famero). <\/li>\n<\/ul>\n<p>Por ejemplo,<\/p>\n<\/li>\n<\/ul>\n<pre lang=\"text\">\n    densidades 100     ==  (0.22,    2.0e-2, 0.76)\n    densidades 1000    ==  (0.246,   3.0e-3, 0.751)\n    densidades 10000   ==  (0.2488,  4.0e-4, 0.7508)\n    densidades 100000  ==  (0.24795, 4.0e-5, 0.75201)\n    densidades 1000000 ==  (0.247545,4.0e-6, 0.752451)\n<\/pre>\n<ul>\n<li><code>(graficas n)<\/code> dibuja las gr\u00e1ficas de las k-\u00e9simas densidades (para k entre 1 y n) de los n\u00fameros abundantes, de los n\u00fameros perfectos y de los n\u00fameros deficientes. Por ejemplo, <code>(graficas 100)<\/code> dibuja<br \/>\n<a href=\"https:\/\/i0.wp.com\/www.glc.us.es\/~jalonso\/exercitium\/wp-content\/uploads\/2017\/04\/Densidad_de_numeros_abundantes1.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.glc.us.es\/~jalonso\/exercitium\/wp-content\/uploads\/2017\/04\/Densidad_de_numeros_abundantes1.png?resize=640%2C480\" alt=\"\" width=\"640\" height=\"480\" class=\"aligncenter size-full wp-image-3194\" srcset=\"https:\/\/i0.wp.com\/www.glc.us.es\/~jalonso\/exercitium\/wp-content\/uploads\/2017\/04\/Densidad_de_numeros_abundantes1.png?w=640&amp;ssl=1 640w, https:\/\/i0.wp.com\/www.glc.us.es\/~jalonso\/exercitium\/wp-content\/uploads\/2017\/04\/Densidad_de_numeros_abundantes1.png?resize=300%2C225&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.glc.us.es\/~jalonso\/exercitium\/wp-content\/uploads\/2017\/04\/Densidad_de_numeros_abundantes1.png?resize=100%2C75&amp;ssl=1 100w, https:\/\/i0.wp.com\/www.glc.us.es\/~jalonso\/exercitium\/wp-content\/uploads\/2017\/04\/Densidad_de_numeros_abundantes1.png?resize=150%2C112&amp;ssl=1 150w\" sizes=\"(max-width: 640px) 100vw, 640px\" data-recalc-dims=\"1\" \/><\/a><br \/>\ny <code>(graficas 400)<\/code> dibuja<br \/>\n<a href=\"https:\/\/i0.wp.com\/www.glc.us.es\/~jalonso\/exercitium\/wp-content\/uploads\/2017\/04\/Densidad_de_numeros_abundantes2.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.glc.us.es\/~jalonso\/exercitium\/wp-content\/uploads\/2017\/04\/Densidad_de_numeros_abundantes2.png?resize=640%2C480\" alt=\"\" width=\"640\" height=\"480\" class=\"aligncenter size-full wp-image-3195\" srcset=\"https:\/\/i0.wp.com\/www.glc.us.es\/~jalonso\/exercitium\/wp-content\/uploads\/2017\/04\/Densidad_de_numeros_abundantes2.png?w=640&amp;ssl=1 640w, https:\/\/i0.wp.com\/www.glc.us.es\/~jalonso\/exercitium\/wp-content\/uploads\/2017\/04\/Densidad_de_numeros_abundantes2.png?resize=300%2C225&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.glc.us.es\/~jalonso\/exercitium\/wp-content\/uploads\/2017\/04\/Densidad_de_numeros_abundantes2.png?resize=100%2C75&amp;ssl=1 100w, https:\/\/i0.wp.com\/www.glc.us.es\/~jalonso\/exercitium\/wp-content\/uploads\/2017\/04\/Densidad_de_numeros_abundantes2.png?resize=150%2C112&amp;ssl=1 150w\" sizes=\"(max-width: 640px) 100vw, 640px\" data-recalc-dims=\"1\" \/><\/a><\/li>\n<\/ul>\n<h4>Soluciones<\/h4>\n<pre lang=\"haskell\">\nimport Data.List (genericLength, group, partition)\nimport Data.Array (accumArray, assocs)\nimport Data.Numbers.Primes (primeFactors)\nimport Graphics.Gnuplot.Simple (plotLists, Attribute (Key))\nimport Test.QuickCheck (Positive (Positive), quickCheck)\n\n-- 1\u00aa soluci\u00f3n\n-- ===========\n\ndensidades1 :: Int -> (Double,Double,Double)\ndensidades1 n = (f a, f p, f d)\n  where a   = nAbundantes n\n        p   = nPerfectos n\n        d   = n - a - p\n        f x = fromIntegral x \/ fromIntegral n\n\n-- (nAbundantes n) es la cantidad de n\u00fameros abundantes desde 1 hasta\n-- n. Por ejemplo,\n--    nAbundantes 100 == 22\nnAbundantes :: Int -> Int\nnAbundantes n = length (filter esAbundante [1..n])\n\n-- (esAbundante n) se verifica si n es un n\u00famero abundante. Por ejemplo,\n--    esAbundante 12 == True\n--    esAbundante 22 == False\nesAbundante :: Int -> Bool\nesAbundante n = sumaDivisores n > n\n\n-- (sumaDivisores n) es la suma de los divisores propios de n. Por\n-- ejemplo,\n--    sumaDivisores 12 == 16\n--    sumaDivisores 22 == 14\nsumaDivisores :: Int -> Int\nsumaDivisores = sum . divisores\n\n-- (divisores n) es la lista de los divisores propios de n. Por ejemplo,\n--    divisores 12== [1,2,3,4,6]\n--    divisores 22== [1,2,11]\ndivisores :: Int -> [Int]\ndivisores n = [x | x <- [1..n-1],\n                   n `mod` x == 0]\n\n-- (nPerfectos n) es la cantidad de n\u00fameros perfectos desde 1 hasta\n-- n. Por ejemplo,\n--    nPerfectos 100 == 2\nnPerfectos :: Int -> Int\nnPerfectos n = length (filter esPerfecto [1..n])\n\n-- (esPerfecto n) se verifica si n es un n\u00famero perfecto. Por ejemplo,\n--    esPerfecto 28 == True\n--    esPerfecto 38 == False\nesPerfecto :: Int -> Bool\nesPerfecto n = sumaDivisores n == n\n\n-- 2\u00aa soluci\u00f3n\n-- ===========\n\ndensidades2 :: Int -> (Double,Double,Double)\ndensidades2 n = (f as, f ps, f ds)\n  where (as,pds) = partition esAbundante [1..n]\n        (ps,ds)  = partition esPerfecto pds\n        f xs     = genericLength xs \/ fromIntegral n\n\n-- 3\u00aa soluci\u00f3n\n-- ===========\n\ndensidades3 :: Int -> (Double,Double,Double)\ndensidades3 n = (f as, f ps, f ds)\n  where cs       = map clasificacion [1..n]\n        (as,pds) = partition (== Abundante) cs\n        (ps,ds)  = partition (== Perfecto) pds\n        f xs     = genericLength xs \/ fromIntegral n\n\ndata Clase = Abundante | Perfecto | Deficiente\n  deriving (Eq, Show)\n\n-- (clasificacion n) es la clase de n\u00famero de n. Por ejemplo,\n--    clasificacion 12 == Abundante\n--    clasificacion 22 == Deficiente\n--    clasificacion 28 == Perfecto\nclasificacion :: Int -> Clase\nclasificacion n\n  | sd > n    = Abundante\n  | sd < n    = Deficiente\n  | otherwise = Perfecto\n  where sd = sumaDivisores n\n\n-- 4\u00aa soluci\u00f3n\n-- ===========\n\ndensidades4 :: Int -> (Double,Double,Double)\ndensidades4 n = (f as, f ps, f ds)\n  where cs       = map clasificacion2 [1..n]\n        (as,pds) = partition (== Abundante) cs\n        (ps,ds)  = partition (== Perfecto) pds\n        f xs     = genericLength xs \/ fromIntegral n\n\n-- 2\u00aa definici\u00f3n de clasificacion\nclasificacion2 :: Int -> Clase\nclasificacion2 n\n  | sd > n    = Abundante\n  | sd < n    = Deficiente\n  | otherwise = Perfecto\n  where sd = sumaDivisores2 n\n\n-- 2\u00aa definici\u00f3n de sumaDivisores\nsumaDivisores2 :: Int -> Int\nsumaDivisores2 x =\n  product [(p^(e+1)-1) `div` (p-1) | (p,e) <- factorizacion x] - x\n\n-- (factorizacion x) es la lista de las bases y exponentes de la\n-- descomposici\u00f3n prima de x. Por ejemplo,\n--    factorizacion 600  ==  [(2,3),(3,1),(5,2)]\nfactorizacion :: Int -> [(Int,Int)]\nfactorizacion = map primeroYlongitud . group . primeFactors\n\n-- (primeroYlongitud xs) es el par formado por el primer elemento de xs\n-- y la longitud de xs. Por ejemplo,\n--    primeroYlongitud [3,2,5,7] == (3,4)\nprimeroYlongitud :: [a] -> (a,Int)\nprimeroYlongitud (x:xs) =\n  (x, 1 + length xs)\n\n-- 5\u00aa soluci\u00f3n\n-- ===========\n\ndensidades5 :: Int -> (Double,Double,Double)\ndensidades5 n = (f a, f p, f d)\n  where (a,p,d) = distribucion n\n        f x = fromIntegral x \/ fromIntegral n\n\n-- (distribucion n) es la terna (a,p,d) donde a es la cantidad de\n-- n\u00fameros abundantes de 1 a n, p la de los perfectos y d la de los\n-- deficientes. Por ejemplo,\n--    distribucion 100  ==  (22,2,76)\ndistribucion :: Int -> (Int,Int,Int)\ndistribucion n = aux (0,0,0) (sumaDivisoresHasta n)\n  where aux (a,p,d) [] = (a,p,d)\n        aux (a,p,d) ((x,y):xys)\n          | x < y     = aux (1+a,p,d) xys\n          | x > y     = aux (a,p,1+d) xys\n          | otherwise = aux (a,1+p,d) xys\n\n-- (sumaDivisoresHasta n) es la lista de los pares (a,b) tales que a\n-- var\u00eda entre 1 y n y b es la suma de los divisores propios de a. Por\n-- ejemplo,\n--    \u03bb> sumaDivisoresHasta 12\n--    [(1,0),(2,1),(3,1),(4,3),(5,1),(6,6),(7,1),(8,7),(9,4),(10,8),(11,1),(12,16)]\nsumaDivisoresHasta :: Int -> [(Int,Int)]\nsumaDivisoresHasta n =\n  assocs (accumArray (+) 0 (1,n) (divisoresHasta n))\n\n-- (divisoresHasta n) es la lista de los pares (a,b) tales que a est\u00e1\n-- entre 2 y n y b es un divisor propio e x. Por ejemplo,\n--    \u03bb> divisoresHasta 6\n--    [(2,1),(3,1),(4,1),(5,1),(6,1),(4,2),(6,2),(6,3)]\n--    \u03bb> divisoresHasta 8\n--    [(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),(4,2),(6,2),(8,2),(6,3),(8,4)]\ndivisoresHasta :: Int -> [(Int,Int)]\ndivisoresHasta n = [(a,b) | b <- [1..n `div` 2], a <- [b*2, b*3..n]]\n\n-- Comprobaci\u00f3n de equivalencia\n-- ============================\n\n-- La propiedad es\nprop_densidades :: Positive Int -> Bool\nprop_densidades (Positive n) =\n  all (== densidades1 n)\n      [ densidades2 n\n      , densidades3 n\n      , densidades4 n\n      , densidades5 n\n      ]\n\n-- La comprobaci\u00f3n es\n--    \u03bb> quickCheck prop_densidades\n--    +++ OK, passed 100 tests.\n\n-- Comparaci\u00f3n de eficiencia\n-- =========================\n\n-- La comparaci\u00f3n es\n--    \u03bb> densidades1 2000\n--    (0.2465,1.5e-3,0.752)\n--    (1.59 secs, 804,883,768 bytes)\n--    \u03bb> densidades2 2000\n--    (0.2465,1.5e-3,0.752)\n--    (1.39 secs, 704,749,552 bytes)\n--    \u03bb> densidades3 2000\n--    (0.2465,1.5e-3,0.752)\n--    (0.81 secs, 403,783,312 bytes)\n--    \u03bb> densidades4 2000\n--    (0.2465,1.5e-3,0.752)\n--    (0.04 secs, 34,364,960 bytes)\n--    \u03bb> densidades5 2000\n--    (0.2465,1.5e-3,0.752)\n--    (0.02 secs, 4,716,720 bytes)\n--\n--    \u03bb> densidades4 100000\n--    (0.24795,4.0e-5,0.75201)\n--    (1.61 secs, 4,826,971,624 bytes)\n--    \u03bb> densidades5 100000\n--    (0.24795,4.0e-5,0.75201)\n--    (0.43 secs, 291,989,272 bytes)\n\n-- Gr\u00e1fica\n-- =======\n\ngraficas :: Int -> IO ()\ngraficas n =\n  plotLists [Key Nothing]\n            [ [x | (x,_,_) <- ts]\n            , [y | (_,y,_) <- ts]\n            , [z | (_,_,z) <- ts]]\n  where ts = [densidades5 k | k <- [1..n]]\n<\/pre>\n<p>El c\u00f3digo se encuentra en <a href=\"https:\/\/github.com\/jaalonso\/Exercitium\/blob\/main\/src\/Densidad_de_numeros_abundantes.hs\">GitHub<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>La n-\u00e9sima densidad de un tipo de n\u00famero es el cociente entre la cantidad de los n\u00fameros entre 1 y n que son del tipo considerado y n. Por ejemplo, la 7-\u00e9sima densidad de los m\u00faltiplos de 3 es 2\/7 ya que entre los 7 primeros n\u00fameros s\u00f3lo 2 son m\u00faltiplos de 3. Definir las&#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\/7034"}],"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=7034"}],"version-history":[{"count":9,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/7034\/revisions"}],"predecessor-version":[{"id":7043,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/7034\/revisions\/7043"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/media?parent=7034"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/categories?post=7034"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/tags?post=7034"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}