Ir al contenido principal

Primos equidistantes

Definir la función

primosEquidistantes :: Integer -> [(Integer,Integer)]

tal que (primosEquidistantes k) es la lista de los pares de primos consecutivos cuya diferencia es k. Por ejemplo,

take 3 (primosEquidistantes 2)     ==  [(3,5),(5,7),(11,13)]
take 3 (primosEquidistantes 4)     ==  [(7,11),(13,17),(19,23)]
take 3 (primosEquidistantes 6)     ==  [(23,29),(31,37),(47,53)]
take 3 (primosEquidistantes 8)     ==  [(89,97),(359,367),(389,397)]
(primosEquidistantes 30) !! 14000  ==  (6557303,6557333)

Soluciones

import Data.Numbers.Primes (primes)

-- 1ª definición
-- =============

primosEquidistantes :: Integer -> [(Integer,Integer)]
primosEquidistantes k = aux primos
  where aux (x:y:ps) | y - x == k = (x,y) : aux (y:ps)
                     | otherwise  = aux (y:ps)
        aux _                     = []

-- (primo x) se verifica si x es primo. Por ejemplo,
--    primo 7  ==  True
--    primo 8  ==  False
primo :: Integer -> Bool
primo x = [y | y <- [1..x], x `rem` y == 0] == [1,x]

-- primos es la lista de los números primos. Por ejemplo,
--    take 10 primos  ==  [2,3,5,7,11,13,17,19,23,29]
primos :: [Integer]
primos = 2 : [x | x <- [3,5..], primo x]

-- 2ª definición
-- =============

primosEquidistantes2 :: Integer -> [(Integer,Integer)]
primosEquidistantes2 k = aux primes
  where aux (x:y:ps) | y - x == k = (x,y) : aux (y:ps)
                     | otherwise  = aux (y:ps)
        aux _                     = []

-- 3ª definición
-- =============

primosEquidistantes3 :: Integer -> [(Integer,Integer)]
primosEquidistantes3 k =
  [(x,y) | (x,y) <- zip primes (tail primes)
         , y - x == k]


-- Comparación de eficiencia
-- =========================

--    λ> (primosEquidistantes 10) !! 150
--    (13513,13523)
--    (2.18 secs, 1,325,730,640 bytes)
--    λ> (primosEquidistantes2 10) !! 150
--    (13513,13523)
--    (0.01 secs, 0 bytes)
--    > (primosEquidistantes3 10) !! 150
--    (13513,13523)
--    (0.01 secs, 8,558,304 bytes)
--
--    λ> (primosEquidistantes2 10) !! 25000
--    (4195579,4195589)
--    (0.87 secs, 1,732,746,232 bytes)
--    λ> (primosEquidistantes3 10) !! 25000
--    (4195579,4195589)
--    (1.64 secs, 3,369,780,400 bytes)