Ir al contenido principal

Primos gemelos próximos a múltiplos de 6

Un par de números primos (p,q) es un par de números primos gemelos si su distancia de 2; es decir, si q = p+2. Por ejemplo, (17,19) es una par de números primos gemelos.

Se dice que un par de números (x,y) está próximo a un múltiplo de 6 si es de la forma (6n-1,6n+1). Por ejemplo, (17,19) está cerca de un múltiplo de 6 porque (17,19) = (6·3-1,6·3+1).

Definir las funciones

primosGemelos :: Integer -> [(Integer,Integer)]
primosGemelosNoProximosAmultiplosDe6 :: Integer -> [(Integer,Integer)]

tales que

  • (primosGemelos n) es la lista de los primos gemelos menores que n. Por ejemplo,
primosGemelos 50  == [(3,5),(5,7),(11,13),(17,19),(29,31),(41,43)]
primosGemelos 43  == [(3,5),(5,7),(11,13),(17,19),(29,31)]
  • (primosGemelosNoProximosAmultiplosDe6 n) es la lista de los primos gemelos menores que n que no están próximos a un múltiplo de 6. Por ejemplo,
primosGemelosNoProximosAmultiplosDe6 50               == [(3,5)]
length (primosGemelosNoProximosAmultiplosDe6' (10^9)) == 1

Soluciones

primosGemelos :: Integer -> [(Integer,Integer)]
primosGemelos n = [(x,x+2) | x <- [3,5..n-3],
                             primo x,
                             primo (x+2)]

primo :: Integer -> Bool
primo n = divisores n == [1,n]

divisores :: Integer -> [Integer]
divisores n = [x | x <- [1..n], n `mod` x == 0]

proximosAmultiplosDe6 :: (Integer,Integer) -> Bool
proximosAmultiplosDe6 (x,y) =
    (x+1) `mod` 6 == 0 && y == 6*n+1
    where n = (x+1) `div` 6

primosGemelosNoProximosAmultiplosDe6 :: Integer -> [(Integer,Integer)]
primosGemelosNoProximosAmultiplosDe6 n =
    [p | p <- primosGemelos n,
         not (proximosAmultiplosDe6 p)]


-- Experimentado con primosGemelosNProximosAmultiplosDe6
--    primosGemelosNoProximosAmultiplosDe6 50    == [(3,5)]
--    primosGemelosNoProximosAmultiplosDe6 500   == [(3,5)]
--    primosGemelosNoProximosAmultiplosDe6 5000  == [(3,5)]
-- se observa que el único par de primos gemelos no próximos a múltiplos
-- de 6 es el (3,5). Su demostración es la siguiente:
--
-- Para cualquier n > 3, se tiene que de los tres números n-1, n. n+1
-- uno es divisible por 2 y alguno es divisible por 3. Si n-1 y n+1 son
-- primos, entonces el que es divisible por 2 y por 3 es n y, por tanto,
-- n es divisible por 6 y (n-1,n+1) están próximos a un múltiplo de 6.

-- Usando la propiedad tenemos una definición más eficiente
primosGemelosNoProximosAmultiplosDe6' :: Integer -> [(Integer,Integer)]
primosGemelosNoProximosAmultiplosDe6' n = [(3,5)]