Raíces enteras de los números primos
Definir la sucesión
raicesEnterasDePrimos :: [Integer]
cuyos elementos son las partes enteras de las raíces cuadradas de los números primos. Por ejemplo,
λ> take 30 raicesEnterasDePrimos [1,1,2,2,3,3,4,4,4,5,5,6,6,6,6,7,7,7,8,8,8,8,9,9,9,10,10,10,10,10] λ> raicesEnterasDePrimos !! 9963 322 λ> raicesEnterasDePrimos !! 9964 323
Comprobar con QuickCheck que la diferencia entre dos términos consecutivos de la sucesión es como máximo igual a 1.
Soluciones
import Data.Numbers.Primes (primes) import Test.QuickCheck -- 1ª solución -- =========== raicesEnterasDePrimos1 :: [Integer] raicesEnterasDePrimos1 = map raizEntera primes -- (raizEntera x) es la parte entera de la raíz cuadrada de x. Por -- ejemplo, -- raizEntera 8 == 2 -- raizEntera 9 == 3 -- raizEntera 10 == 3 raizEntera :: Integer -> Integer raizEntera = floor . sqrt . fromIntegral -- 2ª solución -- =========== raicesEnterasDePrimos2 :: [Integer] raicesEnterasDePrimos2 = map raizEntera2 primes raizEntera2 :: Integer -> Integer raizEntera2 n = aux 1 where aux k | k*k > n = k-1 | otherwise = aux (k+1) -- 3º solución -- =========== raicesEnterasDePrimos3 :: [Integer] raicesEnterasDePrimos3 = aux primes [1..] where aux (p:ps) (x:xs) | p > x*x = aux (p:ps) xs | otherwise = (x-1) : aux ps (x:xs) -- Comparación de eficiencia -- λ> raicesEnterasDePrimos1 !! 400000 -- 2408 -- (2.86 secs, 1177922500 bytes) -- λ> raicesEnterasDePrimos2 !! 400000 -- 2408 -- (3.08 secs, 1177432260 bytes) -- λ> raicesEnterasDePrimos3 !! 400000 -- 2408 -- (3.88 secs, 1260772112 bytes) -- En lo sucesivo usaremos la 1ª definición raicesEnterasDePrimos :: [Integer] raicesEnterasDePrimos = raicesEnterasDePrimos3 -- La propiedad es prop_raicesEnterasDePrimos :: Int -> Property prop_raicesEnterasDePrimos n = n >= 0 ==> raicesEnterasDePrimos !! (n+1) - raicesEnterasDePrimos !! n <= 1 -- La comprobación es -- λ> quickCheck prop_raicesEnterasDePrimos -- +++ OK, passed 100 tests.