Menu Close

Cadena de primos

La lista de los primeros números primos es

   [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71]

Los primeros elementos de la cadena obtenida concatenado los números primos es

   "23571113171923293137414347535961677173798389971011"

Definir la función

   primoEnPosicion :: Int -> Integer

tal que (primoEnPosicion n) es el número primo que tiene algún dígito en la posición n de la cadena obtenida concatenado los números primos. Por ejemplo,

   primoEnPosicion 0       ==  2
   primoEnPosicion 1       ==  3
   primoEnPosicion 4       ==  11
   primoEnPosicion 5       ==  11
   primoEnPosicion 6       ==  13
   primoEnPosicion 1022    ==  2011
   primoEnPosicion 1023    ==  2017
   primoEnPosicion 1026    ==  2017
   primoEnPosicion 1027    ==  2027
   primoEnPosicion (10^7)  ==  21242357

Soluciones

import Data.Numbers.Primes
import Test.QuickCheck
 
-- 1ª definición
-- =============
 
primoEnPosicion :: Int -> Integer
primoEnPosicion = aux primes
  where aux (x:xs) n | m > n     = x
                     | otherwise = aux xs (n-m)
          where m = length (show x)
 
 
-- 2ª definición
-- =============
 
primoEnPosicion2 :: Int -> Integer
primoEnPosicion2 n = p
  where (p,_) = head $ dropWhile (\(x,k) -> k < n) primosYfinales
 
-- primosYfinales es la sucesión de los pares de los números primos y
-- las posiciones de sus dígitos finales en la sucesión de la
-- concatenación de primos. Por ejemplo, 
--    λ> take 10 primosYfinales
--    [(2,0),(3,1),(5,2),(7,3),(11,5),(13,7),(17,9),(19,11),(23,13),(29,15)]
primosYfinales :: [(Integer, Int)]
primosYfinales = scanl f (2,0) (tail primes)
  where f (p,k) q = (q, k + length (show q))
 
-- Comprobación de equivalencia
-- ============================
 
-- La propiedad es
prop_equivalencia (Positive n) =
  primoEnPosicion n == primoEnPosicion2 n
 
-- La comprobación es  
--    λ> quickCheck prop_equivalencia
--    +++ OK, passed 100 tests.

5 soluciones de “Cadena de primos

  1. enrnarbej
    primoEnPosicion :: Int -> Integer
    primoEnPosicion n = cadena primes !! n
      where
        cadena (x:xs) = replicate ((length . show) x) x ++ cadena xs
  2. Chema Cortés
    import Data.Numbers.Primes (primes)
     
    primoEnPosicion :: Int -> Integer
    primoEnPosicion = primoEnPosicion3
     
    primoEnPosicion1 :: Int -> Integer
    primoEnPosicion1 n = head [ p | (p,x) <- zip primes xs, x > n ]
      where xs = scanl1 (+) $ map (length.show) primes
     
    primoEnPosicion2 :: Int -> Integer
    primoEnPosicion2 n = aux n primes
      where aux n (x:xs) | n <  m     = x
                         | otherwise  = aux (n-m) xs
              where m = (length.show) x
     
    primoEnPosicion3 :: Int -> Integer
    primoEnPosicion3 = (!!) $ concatMap (replicate <$> length.show <*> id) primes
  3. eliguivil
    primoEnPosicion :: Int -> Integer
    primoEnPosicion = aux (aux1 primes)
      where
        aux1 (x:xs) = ((length.show) x, x) : aux1 xs
        aux ((l,p):xs) n
          | l <= n    = aux xs (n-l)
          | otherwise = p
  4. albcercid
    primoEnPosicion :: Int -> Integer
    primoEnPosicion n = aux n primes
      where aux n (x:xs) | n >= p    = aux (n - p) xs
                         | otherwise = x
              where p = length (show x)
  5. Juanjo Ortega (juaorture)
    import Data.Numbers.Primes
     
    primoEnPosicion :: Int -> Integer
    primoEnPosicion n = read $ cogeEl n cadenaDePrimos []
     
    cadenaDePrimos :: [String]
    cadenaDePrimos = map show primes
     
    cogeEl :: Int -> [[a]] -> [a] -> [a]
    cogeEl n ([]:xss)     _              = cogeEl n xss []
    cogeEl n ((x:xs):xss) ys | n <= 0    = reverse ys ++ (x:xs) 
                             | otherwise = cogeEl (n-1) (xs:xss) (x:ys)

Escribe tu solución

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.