Número de divisores
Definir la función
numeroDivisores :: Integer -> Integer
tal que (numeroDivisores x) es el número de divisores de x. Por ejemplo,
numeroDivisores 12 == 6 numeroDivisores 25 == 3 length (show (numeroDivisores (product (take 20000 primes)))) == 6021
Soluciones
import Data.List (genericLength, group, inits, sort) import Data.Numbers.Primes (primes, primeFactors) -- 1ª definición -- ============= numeroDivisores1 :: Integer -> Integer numeroDivisores1 = genericLength . divisores -- (divisores x) es la lista de los divisores de x. Por ejemplo, -- divisores 12 == [1,2,3,4,6,12] -- divisores 25 == [1,5,25] divisores :: Integer -> [Integer] divisores = sort . map (product . concat) . productoCartesiano . map inits . group . primeFactors -- (producto xss) es el producto cartesiano de los conjuntos xss. Por -- ejemplo, -- λ> producto [[1,3],[2,5],[6,4]] -- [[1,2,6],[1,2,4],[1,5,6],[1,5,4],[3,2,6],[3,2,4],[3,5,6],[3,5,4]] productoCartesiano :: [[a]] -> [[a]] productoCartesiano [] = [[]] productoCartesiano (xs:xss) = [x:ys | x <- xs, ys <- productoCartesiano xss] -- 2ª definición -- ============= numeroDivisores2 :: Integer -> Integer numeroDivisores2 = product . map ((+1) . genericLength) . group . primeFactors -- Comparación de la eficiencia -- ============================ -- λ> numeroDivisores1 (product [1..12]) -- 792 -- (3.09 secs, 1,024,939,296 bytes) -- λ> numeroDivisores2 (product [1..12]) -- 792 -- (0.01 secs, 156,840 bytes) -- -- λ> length (show (numeroDivisores1 (product (take 19 primes)))) -- 6 -- (13.57 secs, 3,458,747,288 bytes) -- λ> length (show (numeroDivisores2 (product (take 19 primes)))) -- 6 -- (0.01 secs, 234,656 bytes)