Paridad del número de divisores
Definir la función
1 |
nDivisoresPar :: Integer -> Bool |
tal que (nDivisoresPar n) se verifica si n tiene un número par de divisores. Por ejemplo,
1 2 3 |
nDivisoresPar 12 == True nDivisoresPar 16 == False nDivisoresPar (product [1..2*10^4]) == True |
Soluciones
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
import Data.List (group) import Data.Numbers.Primes (primeFactors) -- 1ª definición -- ============= nDivisoresPar1 :: Integer -> Bool nDivisoresPar1 = even . length . divisores -- (divisores n) es la lista de los divisores de n. Por ejemplo, -- divisores 12 == [1,2,3,4,6,12] -- divisores 16 == [1,2,4,8,16] divisores :: Integer -> [Integer] divisores n = [x | x <- [1..n], n `mod` x == 0] -- 2ª definición -- ============= nDivisoresPar2 :: Integer -> Bool nDivisoresPar2 n = any odd (map length (group (primeFactors n))) -- Comparación de eficiencia -- ========================= -- λ> nDivisoresPar1 (10^7) -- True -- (14.18 secs, 2,078,736,992 bytes) -- λ> nDivisoresPar2 (10^7) -- True -- (0.01 secs, 0 bytes) -- -- λ> nDivisoresPar2 (product [1..2*10^4]) -- True -- (2.30 secs, 1,003,013,112 bytes) |
Solución en Maxima
1 2 3 4 5 6 7 8 9 10 11 |
/* concat(xs) es la lista obtenida concatenado los elementos de xss. Por ejemplo, concat([[1,3],[2,4],[5,7]]) == [1, 3, 2, 4, 5, 7] */ concat (xs) := block ([r:[]], for x in reverse (xs) do r : append (x,r), r)$ nDivisoresPares (n) := block( [xs : concat (map (rest, ifactors (n))), p : false], for x in xs do p: oddp (x) or p, p)$ |