Alturas primas
Se considera una enumeración de los números primos:
1 |
p(1)=2, p(2)=3, p(3)=5, p(4)=7, p(5)=11, p(6)=13, p(7)=17,... |
Dado un entero x > 1, su altura prima es el mayor i tal que el primo p(i) aparece en la factorización de x en números primos. Por ejemplo, la altura prima de 3500 tiene longitud 4, pues 3500=2^2×5^3×7^1 y la de 34 tiene es 7, pues 34 = 2×17. Además, se define la altura prima de 1 como 0.
Definir las funciones
1 2 3 |
alturaPrima :: Integer -> Integer alturasPrimas :: Integer -> [Integer] graficaAlturaPrima :: Integer -> IO () |
tales que
- (alturaPrima x) es la altura prima de x. Por ejemplo,
1 2 |
alturaPrima 3500 == 4 alturaPrima 34 == 7 |
- (alturasPrimas n) es la lista de las altura prima de los primeros n números enteros positivos. Por ejemplo,
1 2 3 4 5 |
alturasPrimas 15 == [0,1,2,1,3,2,4,1,2,3,5,2,6,4,3] maximum (alturasPrimas 10000) == 1229 maximum (alturasPrimas 20000) == 2262 maximum (alturasPrimas 30000) == 3245 maximum (alturasPrimas 40000) == 4203 |
- (graficaAlturaPrima n) dibuja las alturas primas de los números entre 2 y n. Por ejemplo, (graficaAlturaPrima 500) dibuja
Soluciones
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
import Data.List (genericLength) import Data.Numbers.Primes (isPrime, primes, primeFactors) import Data.Array import Graphics.Gnuplot.Simple -- 1ª definicioń de alturaPrima -- ============================ alturaPrima :: Integer -> Integer alturaPrima 1 = 0 alturaPrima n = indice (mayorFactorPrimo n) -- (mayorFactorPrimo n) es el mayor factor primo de n. Por ejemplo, -- mayorFactorPrimo 3500 == 7 -- mayorFactorPrimo 34 == 17 mayorFactorPrimo :: Integer -> Integer mayorFactorPrimo = last . primeFactors -- (indice p) es el índice de p en la sucesión de los números -- primos. Por ejemplo, -- indice 7 == 4 -- indice 17 == 7 indice :: Integer -> Integer indice p = genericLength (takeWhile (<=p) primes) -- 2ª definicioń de alturaPrima -- ============================ alturaPrima2 :: Integer -> Integer alturaPrima2 n = v ! n where v = array (1,n) [(i,f i) | i <- [1..n]] f 1 = 0 f k | isPrime k = indice2 k | otherwise = v ! (k `div` (head (primeFactors k))) indice2 :: Integer -> Integer indice2 p = head [n | (x,n) <- indicesPrimos, x == p] -- indicesPrimos es la suceción formada por los números primos y sus -- índices. Por ejemplo, -- λ> take 10 indicesPrimos -- [(2,1),(3,2),(5,3),(7,4),(11,5),(13,6),(17,7),(19,8),(23,9),(29,10)] indicesPrimos :: [(Integer,Integer)] indicesPrimos = zip primes [1..] -- 1ª definición de alturasPrimas -- ============================== alturasPrimas :: Integer -> [Integer] alturasPrimas n = map alturaPrima [1..n] -- 2ª definición de alturasPrimas -- ============================== alturasPrimas2 :: Integer -> [Integer] alturasPrimas2 n = elems v where v = array (1,n) [(i,f i) | i <- [1..n]] f 1 = 0 f k | isPrime k = indice2 k | otherwise = v ! (k `div` (head (primeFactors k))) -- Comparación de eficiencia -- ========================= -- λ> maximum (alturasPrimas 20000) -- 2262 -- (29.97 secs, 13,179,984,536 bytes) -- λ> maximum (alturasPrimas2 20000) -- 2262 -- (2.11 secs, 455,259,448 bytes) -- Definición de graficaAlturaPrima -- ================================ graficaAlturaPrima :: Integer -> IO () graficaAlturaPrima n = plotList [ Key Nothing , PNG "Alturas_primas.png" ] (alturasPrimas2 n) |
3 Comentarios