El primorial de un número natural n es el producto de todos los números primos menores o iguales a n. Por ejemplo, el primorial de 5 es 30 porque el producto de los primos menores o iguales que 5 es
2 * 3 * 5 = 30 |
La propiedad de Erdös de acotación de los primoriales afirma que
Para todo número natural n, su primorial es menor o igual que 4ⁿ.
Definir las funciones
primorial :: Integer -> Integer primoriales :: [Integer] |
tales que
- (primorial n) es el primorial de n. Por ejemplo,
primorial 3 == 6 primorial 5 == 30 primorial 8 == 210 |
- primoriales es la sucesión de los primoriales. Por ejemplo,
λ> take 15 primoriales [1,1,2,6,6,30,30,210,210,210,210,2310,2310,30030,30030] |
Comprobar con QuickCheck la propiedad de Erdös de acotación de los primoriales.
Soluciones
import Data.Numbers.Primes import Test.QuickCheck -- 1ª definición de primorial -- ========================== primorial :: Integer -> Integer primorial n = product (takeWhile (<= n) primes) -- 2ª definición de primorial -- ========================== primorial2 :: Integer -> Integer primorial2 0 = 1 primorial2 n | gcd n x == 1 = n*x | otherwise = x where x = primorial2 (n-1) -- Comparación de eficiencia -- ========================= -- λ> length (show (primorial (5*10^5))) -- 216852 -- (1.65 secs, 2,472,977,584 bytes) -- λ> length (show (primorial2 (5*10^5))) -- 216852 -- (3.56 secs, 2,719,162,272 bytes) -- 1ª definición de primoriales -- ============================ -- λ> take 15 primoriales -- [1,1,2,6,6,30,30,210,210,210,210,2310,2310,30030,30030] primoriales :: [Integer] primoriales = map primorial [0..] -- 2ª definición de primoriales -- ============================ -- λ> take 15 primoriales2 -- [1,1,2,6,6,30,30,210,210,210,210,2310,2310,30030,30030] primoriales2 :: [Integer] primoriales2 = map primorial2 [0..] -- 3ª definición de primoriales -- ============================ -- λ> take 15 primoriales3 -- [1,1,2,6,6,30,30,210,210,210,210,2310,2310,30030,30030] primoriales3 :: [Integer] primoriales3 = scanl1 f [1..] where f x n | gcd n x == 1 = n*x | otherwise = x -- Comparación de eficiencia -- ========================= -- λ> minimum (take 5000 primoriales) -- 1 -- (1.56 secs, 4,857,760,464 bytes) -- λ> minimum (take 5000 primoriales2) -- 1 -- (9.39 secs, 10,942,848,240 bytes) -- λ> minimum (take 5000 primoriales3) -- 1 -- (0.01 secs, 5,575,024 bytes) -- -- λ> minimum (take 6000 primoriales) -- 1 -- (2.22 secs, 7,013,937,248 bytes) -- λ> minimum (take 6000 primoriales3) -- 1 -- (0.01 secs, 6,737,328 bytes) -- Propiedad -- ========= prop_primorial :: Integer -> Property prop_primorial n = n >= 0 ==> primorial n <= 4^n -- La comprobación es -- λ> quickCheck prop_primorial -- +++ OK, passed 100 tests. |
Otras soluciones
- Se pueden escribir otras soluciones en los comentarios.
- El código se debe escribir entre una línea con <pre lang=»haskell»> y otra con </pre>
Pensamiento
«Las matemáticas son la reina de las ciencias y la teoría de los números es la reina de las matemáticas.»
Una variante de la definición de primorial sería la siguiente: