Impares en filas del triángulo de Pascal
El triángulo de Pascal es un triángulo de números
1 2 3 4 5 6 7 |
1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 ............... |
construido de la siguiente forma
- la primera fila está formada por el número 1;
- las filas siguientes se construyen sumando los números adyacentes de la fila superior y añadiendo un 1 al principio y al final de la fila.
Definir las funciones
1 2 3 |
imparesPascal :: [[Integer]] nImparesPascal :: [Int] grafica_nImparesPascal :: Int -> IO () |
tales que
- imparesPascal es la lista de los elementos impares en cada una de las filas del triángulo de Pascal. Por ejemplo,
1 2 |
λ> take 8 imparesPascal [[1],[1,1],[1,1],[1,3,3,1],[1,1],[1,5,5,1],[1,15,15,1],[1,7,21,35,35,21,7,1]] |
- nImparesPascal es la lista del número de elementos impares en cada una de las filas del triángulo de Pascal. Por ejemplo,
1 2 3 4 |
λ> take 32 nImparesPascal [1,2,2,4,2,4,4,8,2,4,4,8,4,8,8,16,2,4,4,8,4,8,8,16,4,8,8,16,8,16,16,32] λ> maximum (take (10^6) nImparesPascal3) 524288 |
(grafica_nImparesPascal n)
dibuja la gráfica de los n primeros términos de nImparesPascal. Por ejemplo,(grafica_nImparesPascal 50)
dibuja
y (grafica_nImparesPascal 100)
dibuja
Comprobar con QuickCheck que todos los elementos de nImparesPascal son potencias de dos.
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 81 82 83 84 85 86 87 |
import Data.List (transpose) import Test.QuickCheck import Graphics.Gnuplot.Simple -- 1ª definición de imparesPascal -- ============================== imparesPascal :: [[Integer]] imparesPascal = map (filter odd) pascal -- pascal es la lista de las filas del triángulo de Pascal. Por ejemplo, -- λ> take 7 pascal -- [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1],[1,5,10,10,5,1],[1,6,15,20,15,6,1]] pascal :: [[Integer]] pascal = [1] : map f pascal where f xs = zipWith (+) (0:xs) (xs++[0]) -- 2ª definición de imparesPascal -- ============================== imparesPascal2 :: [[Integer]] imparesPascal2 = map (filter odd) pascal pascal2 :: [[Integer]] pascal2 = iterate f [1] where f xs = zipWith (+) (0:xs) (xs++[0]) -- 1ª definición de nImparesPascal -- =============================== nImparesPascal :: [Int] nImparesPascal = map length imparesPascal -- 2ª definición de nImparesPascal -- =============================== nImparesPascal2 :: [Int] nImparesPascal2 = map (length . filter odd) imparesPascal -- 3ª definición de nImparesPascal -- =============================== -- λ> take 32 nImparesPascal2 -- [1,2, -- 2,4, -- 2,4,4,8, -- 2,4,4,8,4,8,8,16, -- 2,4,4,8,4,8,8,16,4,8,8,16,8,16,16,32] nImparesPascal3 :: [Int] nImparesPascal3 = 1 : zs where zs = 2 : concat (transpose [zs, map (*2) zs]) -- Definición de grafica_nImparesPascal -- ========================================= grafica_nImparesPascal :: Int -> IO () grafica_nImparesPascal n = plotListStyle [ Key Nothing , PNG ("Impares_en_filas_del_triangulo_de_Pascal_" ++ show n ++ ".png") ] (defaultStyle {plotType = LinesPoints}) (take n nImparesPascal3) -- Propiedad de nImparesPascal -- =========================== -- La propiedad es prop_nImparesPascal :: Positive Int -> Bool prop_nImparesPascal (Positive n) = esPotenciaDeDos (nImparesPascal3 !! n) -- (esPotenciaDeDos n) se verifica si n es una potencia de dos. Por -- ejemplo, -- esPotenciaDeDos 16 == True -- esPotenciaDeDos 18 == False esPotenciaDeDos :: Int -> Bool esPotenciaDeDos 1 = True esPotenciaDeDos n = even n && esPotenciaDeDos (n `div` 2) -- La comprobación es -- λ> quickCheck prop_nImparesPascal -- +++ OK, passed 100 tests. |
Pensamiento
De lo que llaman los hombres
virtud, justicia y bondad,
una mitad es envidia,
y la otra no es caridad.Antonio Machado