Conjunto de primos relativos
Dos números enteros positivos son primos relativos si no tienen ningún factor primo en común; es decit, si 1 es su único divisor común. Por ejemplo, 6 y 35 son primos entre sí, pero 6 y 27 no lo son porque ambos son divisibles por 3.
Definir la función
1 |
primosRelativos :: [Int] -> Bool |
tal que (primosRelativos xs)
se verifica si los elementos de xs
son primos relativos dos a dos. Por ejemplo,
1 2 3 4 5 6 |
primosRelativos [6,35] == True primosRelativos [6,27] == False primosRelativos [2,3,4] == False primosRelativos [6,35,11] == True primosRelativos [6,35,11,221] == True primosRelativos [6,35,11,231] == False |
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 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
import Test.QuickCheck import Data.List (delete, intersect) import Data.Numbers.Primes (primeFactors, primes) import qualified Data.Set as S (disjoint, fromList) -- 1ª solución -- =========== primosRelativos1 :: [Int] -> Bool primosRelativos1 [] = True primosRelativos1 (x:xs) = and [sonPrimosRelativos1 x y | y <- xs] && primosRelativos1 xs -- (sonPrimosRelativos x y) se verifica si x e y son primos -- relativos. Por ejemplo, -- sonPrimosRelativos1 6 35 == True -- sonPrimosRelativos1 6 27 == False sonPrimosRelativos1 :: Int -> Int -> Bool sonPrimosRelativos1 x y = null (divisoresPrimos x `intersect` divisoresPrimos y) -- (divisoresPrimos x) es la lista de los divisores primos de x. Por -- ejemplo, -- divisoresPrimos 600 == [2,2,2,3,5,5] divisoresPrimos :: Int -> [Int] divisoresPrimos 1 = [] divisoresPrimos x = y : divisoresPrimos (x `div` y) where y = menorDivisorPrimo x -- (menorDivisorPrimo x) es el menor divisor primo de x. Por ejemplo, -- menorDivisorPrimo 15 == 3 -- menorDivisorPrimo 11 == 11 menorDivisorPrimo :: Int -> Int menorDivisorPrimo x = head [y | y <- [2..], x `mod` y == 0] -- 2ª solución -- =========== primosRelativos2 :: [Int] -> Bool primosRelativos2 [] = True primosRelativos2 (x:xs) = all (sonPrimosRelativos1 x) xs && primosRelativos2 xs -- 3ª solución -- =========== primosRelativos3 :: [Int] -> Bool primosRelativos3 [] = True primosRelativos3 (x:xs) = all (sonPrimosRelativos2 x) xs && primosRelativos3 xs sonPrimosRelativos2 :: Int -> Int -> Bool sonPrimosRelativos2 x y = null (primeFactors x `intersect` primeFactors y) -- 4ª solución -- =========== primosRelativos4 :: [Int] -> Bool primosRelativos4 [] = True primosRelativos4 (x:xs) = all (sonPrimosRelativos3 x) xs && primosRelativos4 xs sonPrimosRelativos3 :: Int -> Int -> Bool sonPrimosRelativos3 x y = S.fromList (primeFactors x) `S.disjoint` S.fromList (primeFactors y) -- 5ª solución -- =========== primosRelativos5 :: [Int] -> Bool primosRelativos5 [] = True primosRelativos5 (x:xs) = all (sonPrimosRelativos5 x) xs && primosRelativos5 xs sonPrimosRelativos5 :: Int -> Int -> Bool sonPrimosRelativos5 x y = gcd x y == 1 -- Comprobación de equivalencia -- ============================ -- La propiedad es prop_primosRelativos :: [Positive Int] -> Bool prop_primosRelativos xs = all (== primosRelativos1 ys) [primosRelativos2 ys, primosRelativos3 ys, primosRelativos4 ys, primosRelativos5 ys] where ys = getPositive <$> xs -- La comprobación es -- λ> quickCheck prop_primosRelativos -- +++ OK, passed 100 tests. -- Comparación de eficiencia -- ========================= -- La comparación es -- λ> primosRelativos1 (take 120 primes) -- True -- (1.92 secs, 869,909,416 bytes) -- λ> primosRelativos2 (take 120 primes) -- True -- (1.99 secs, 869,045,656 bytes) -- λ> primosRelativos3 (take 120 primes) -- True -- (0.09 secs, 221,183,200 bytes) -- -- λ> primosRelativos3 (take 600 primes) -- True -- (2.62 secs, 11,196,690,856 bytes) -- λ> primosRelativos4 (take 600 primes) -- True -- (2.66 secs, 11,190,940,456 bytes) -- λ> primosRelativos5 (take 600 primes) -- True -- (0.14 secs, 123,673,648 bytes) |
El código se encuentra en GitHub.
La elaboración de las soluciones se describe en el siguiente vídeo
Nuevas soluciones
- En los comentarios se pueden escribir nuevas soluciones.
- El código se debe escribir entre una línea con <pre lang="haskell"> y otra con </pre>