Números triangulares
La sucesión de los números triangulares se obtiene sumando los números naturales.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 1 3 6 10 15
Así, los 5 primeros números triangulares son
1 = 1 3 = 1+2 6 = 1+2+3 10 = 1+2+3+4 15 = 1+2+3+4+5
Definir la función
triangulares :: [Integer]
tal que triangulares es la lista de los números triangulares. Por ejemplo,
take 10 triangulares == [1,3,6,10,15,21,28,36,45,55] maximum (take (5*10^6) triangulares4) == 12500002500000
Comprobar con QuickCheck que entre dos números triangulares consecutivos siempre hay un número primo.
Soluciones
import Test.QuickCheck (Property, (==>), quickCheck) import Data.Numbers.Primes (primes) -- 1ª solución -- =========== triangulares :: [Integer] triangulares = [sum [1..n] | n <- [1..]] -- 2ª solución -- =========== triangulares2 :: [Integer] triangulares2 = map triangular [1..] -- (triangular n) es el n-ésimo número triangular. Por ejemplo, -- triangular 5 == 15 triangular :: Integer -> Integer triangular 1 = 1 triangular n = n + triangular (n-1) -- 3ª solución -- =========== triangulares3 :: [Integer] triangulares3 = 1 : [x+y | (x,y) <- zip [2..] triangulares] -- 4ª solución -- =========== triangulares4 :: [Integer] triangulares4 = scanl1 (+) [1..] -- 5ª solución -- =========== triangulares5 :: [Integer] triangulares5 = [(n*(n+1)) `div` 2 | n <- [1..]] -- Comparación de eficiencia -- ========================= -- λ> maximum (take (10^4) triangulares) -- 50005000 -- (2.10 secs, 8,057,774,104 bytes) -- λ> maximum (take (10^4) triangulares2) -- 50005000 -- (18.89 secs, 12,142,690,784 bytes) -- λ> maximum (take (10^4) triangulares3) -- 50005000 -- (0.01 secs, 4,600,976 bytes) -- λ> maximum (take (10^4) triangulares4) -- 50005000 -- (0.01 secs, 3,643,192 bytes) -- λ> maximum (take (10^4) triangulares5) -- 50005000 -- (0.02 secs, 5,161,464 bytes) -- -- λ> maximum (take (3*10^4) triangulares3) -- 450015000 -- (26.06 secs, 72,546,027,136 bytes) -- λ> maximum (take (3*10^4) triangulares4) -- 450015000 -- (0.02 secs, 10,711,600 bytes) -- λ> maximum (take (3*10^4) triangulares5) -- 450015000 -- (0.03 secs, 15,272,320 bytes) -- -- λ> maximum (take (5*10^6) triangulares4) -- 12500002500000 -- (1.67 secs, 1,772,410,336 bytes) -- λ> maximum (take (5*10^6) triangulares5) -- 12500002500000 -- (4.09 secs, 2,532,407,720 bytes) -- La propiedad es prop_triangulares :: Int -> Property prop_triangulares n = n >= 0 ==> siguientePrimo x < y where (x:y:_) = drop n primes -- (siguientePrimo n) es el menor primo mayor o igual que n. Por -- ejemplo, -- siguientePrimo 14 == 17 -- siguientePrimo 17 == 17 siguientePrimo :: Integer -> Integer siguientePrimo n = head (dropWhile (< n) primes) -- La comprobación es -- λ> quickCheck prop_triangulares -- +++ OK, passed 100 tests.