En la primera parte de la clase de hoy del curso de Informática de 1º del Grado en Matemáticas se han comentado soluciones de ejercicios de la 3ª relación sobre definiciones por comprensión.
Los ejercicios y su solución se muestran a continuación
-- --------------------------------------------------------------------- -- Ejercicio 11.1. Una terna (x,y,z) de enteros positivos es pitagórica -- si x^2 + y^2 = z^2. -- -- Definir, por comprensión, la función -- pitagoricas :: Int -> [(Int,Int,Int)] -- tal que (pitagoricas n) es la lista de todas las ternas pitagóricas -- cuyas componentes están entre 1 y n. Por ejemplo, -- pitagoricas 10 == [(3,4,5),(4,3,5),(6,8,10),(8,6,10)] -- --------------------------------------------------------------------- pitagoricas :: Int -> [(Int,Int,Int)] pitagoricas n = [(x,y,z) | x <- [1..n] , y <- [1..n] , z <- [1..n] , x^2 + y^2 == z^2] -- --------------------------------------------------------------------- -- Ejercicio 11.2. Definir la función -- numeroDePares :: (Int,Int,Int) -> Int -- tal que (numeroDePares t) es el número de elementos pares de la terna -- t. Por ejemplo, -- numeroDePares (3,5,7) == 0 -- numeroDePares (3,6,7) == 1 -- numeroDePares (3,6,4) == 2 -- numeroDePares (4,6,4) == 3 -- --------------------------------------------------------------------- numeroDePares :: (Int,Int,Int) -> Int numeroDePares (x,y,z) = length [1 | n <- [x,y,z], even n] -- --------------------------------------------------------------------- -- Ejercicio 11.3. Definir la función -- conjetura :: Int -> Bool -- tal que (conjetura n) se verifica si todas las ternas pitagóricas -- cuyas componentes están entre 1 y n tiene un número impar de números -- pares. Por ejemplo, -- conjetura 10 == True -- --------------------------------------------------------------------- conjetura :: Int -> Bool conjetura n = and [odd (numeroDePares t) | t <- pitagoricas n] -- --------------------------------------------------------------------- -- Ejercicio 11.4. Demostrar la conjetura para todas las ternas -- pitagóricas. -- --------------------------------------------------------------------- -- Sea (x,y,z) una terna pitagórica. Entonces x^2+y^2=z^2. Pueden darse -- 4 casos: -- -- Caso 1: x e y son pares. Entonces, x^2, y^2 y z^2 también lo -- son. Luego el número de componentes pares es 3 que es impar. -- -- Caso 2: x es par e y es impar. Entonces, x^2 es par, y^2 es impar y -- z^2 es impar. Luego el número de componentes pares es 1 que es impar. -- -- Caso 3: x es impar e y es par. Análogo al caso 2. -- -- Caso 4: x e y son impares. Entonces, x^2 e y^2 también son impares y -- z^2 es par. Luego el número de componentes pares es 1 que es impar. -- --------------------------------------------------------------------- -- Ejercicio 12.1. (Problema 9 del Proyecto Euler). Una terna pitagórica -- es una terna de números naturales (a,b,c) tal que a<b<c y -- a^2+b^2=c^2. Por ejemplo (3,4,5) es una terna pitagórica. -- -- Definir la función -- ternasPitagoricas :: Integer -> [[Integer]] -- tal que (ternasPitagoricas x) es la lista de las ternas pitagóricas -- cuya suma es x. Por ejemplo, -- ternasPitagoricas 12 == [(3,4,5)] -- ternasPitagoricas 60 == [(10,24,26),(15,20,25)] -- --------------------------------------------------------------------- ternasPitagoricas :: Integer -> [(Integer,Integer,Integer)] ternasPitagoricas x = [(a,b,c) | a <- [1..x], b <- [a+1..x], c <- [x-a-b], b < c, a^2 + b^2 == c^2] -- --------------------------------------------------------------------- -- Ejercicio 12.2. Definir la constante -- euler9 :: Integer -- tal que euler9 es producto abc donde (a,b,c) es la única terna -- pitagórica tal que a+b+c=1000. -- -- Calcular el valor de euler9. -- --------------------------------------------------------------------- euler9 :: Integer euler9 = a*b*c where (a,b,c) = head (ternasPitagoricas 1000) -- El cálculo del valor de euler9 es -- ghci> euler9 -- 31875000 -- --------------------------------------------------------------------- -- Ejercicio 13. El producto escalar de dos listas de enteros xs y ys de -- longitud n viene dado por la suma de los productos de los elementos -- correspondientes. -- -- Definir por comprensión la función -- productoEscalar :: [Int] -> [Int] -> Int -- tal que (productoEscalar xs ys) es el producto escalar de las listas -- xs e ys. Por ejemplo, -- productoEscalar [1,2,3] [4,5,6] == 32 -- --------------------------------------------------------------------- productoEscalar :: [Int] -> [Int] -> Int productoEscalar xs ys = sum [x*y | (x,y) <- zip xs ys] -- --------------------------------------------------------------------- -- Ejercicio 14. Definir, por comprensión, la función -- sumaConsecutivos :: [Int] -> [Int] -- tal que (sumaConsecutivos xs) es la suma de los pares de elementos -- consecutivos de la lista xs. Por ejemplo, -- sumaConsecutivos [3,1,5,2] == [4,6,7] -- sumaConsecutivos [3] == [] -- --------------------------------------------------------------------- sumaConsecutivos :: [Int] -> [Int] sumaConsecutivos xs = [x+y | (x,y) <- zip xs (tail xs)] -- --------------------------------------------------------------------- -- Ejercicio 15. Los polinomios pueden representarse de forma dispersa o -- densa. Por ejemplo, el polinomio 6x^4-5x^2+4x-7 se puede representar -- de forma dispersa por [6,0,-5,4,-7] y de forma densa por -- [(4,6),(2,-5),(1,4),(0,-7)]. -- -- Definir la función -- densa :: [Int] -> [(Int,Int)] -- tal que (densa xs) es la representación densa del polinomio cuya -- representación dispersa es xs. Por ejemplo, -- densa [6,0,-5,4,-7] == [(4,6),(2,-5),(1,4),(0,-7)] -- densa [6,0,0,3,0,4] == [(5,6),(2,3),(0,4)] -- --------------------------------------------------------------------- densa :: [Int] -> [(Int,Int)] densa xs = [(x,y) | (x,y) <- zip [n-1,n-2..0] xs, y /= 0] where n = length xs -- --------------------------------------------------------------------- -- Ejercicio 16. La bases de datos sobre actividades de personas pueden -- representarse mediante listas de elementos de la forma (a,b,c,d), -- donde a es el nombre de la persona, b su actividad, c su fecha de -- nacimiento y d la de su fallecimiento. Un ejemplo es la siguiente que -- usaremos a lo largo de este ejercicio, -- --------------------------------------------------------------------- personas :: [(String,String,Int,Int)] personas = [("Cervantes","Literatura",1547,1616), ("Velazquez","Pintura",1599,1660), ("Picasso","Pintura",1881,1973), ("Beethoven","Musica",1770,1823), ("Poincare","Ciencia",1854,1912), ("Quevedo","Literatura",1580,1654), ("Goya","Pintura",1746,1828), ("Einstein","Ciencia",1879,1955), ("Mozart","Musica",1756,1791), ("Botticelli","Pintura",1445,1510), ("Borromini","Arquitectura",1599,1667), ("Bach","Musica",1685,1750)] -- --------------------------------------------------------------------- -- Ejercicio 16.1. Definir la función -- nombres :: [(String,String,Int,Int)] -> [String] -- tal que (nombres bd) es la lista de los nombres de las personas de la -- base de datos bd. Por ejemplo, -- ghci> nombres personas -- ["Cervantes","Velazquez","Picasso","Beethoven","Poincare", -- "Quevedo","Goya","Einstein","Mozart","Botticelli","Borromini","Bach"] -- --------------------------------------------------------------------- nombres :: [(String,String,Int,Int)] -> [String] nombres bd = [x | (x,_,_,_) <- bd] -- --------------------------------------------------------------------- -- Ejercicio 16.2. Definir la función -- musicos :: [(String,String,Int,Int)] -> [String] -- tal que (musicos bd) es la lista de los nombres de los músicos de la -- base de datos bd. Por ejemplo, -- musicos personas == ["Beethoven","Mozart","Bach"] -- --------------------------------------------------------------------- musicos :: [(String,String,Int,Int)] -> [String] musicos bd = [x | (x,"Musica",_,_) <- bd] -- --------------------------------------------------------------------- -- Ejercicio 16.3. Definir la función -- seleccion :: [(String,String,Int,Int)] -> String -> [String] -- tal que (seleccion bd m) es la lista de los nombres de las personas -- de la base de datos bd cuya actividad es m. Por ejemplo, -- ghci> seleccion personas "Pintura" -- ["Velazquez","Picasso","Goya","Botticelli"] -- ghci> seleccion personas "Musica" -- ["Beethoven","Mozart","Bach"] -- --------------------------------------------------------------------- seleccion :: [(String,String,Int,Int)] -> String -> [String] seleccion bd m = [ x | (x,m',_,_) <- bd, m == m' ] -- --------------------------------------------------------------------- -- Ejercicio 16.4. Definir, usando el apartado anterior, la función -- musicos' :: [(String,String,Int,Int)] -> [String] -- tal que (musicos' bd) es la lista de los nombres de los músicos de la -- base de datos bd. Por ejemplo, -- ghci> musicos' personas -- ["Beethoven","Mozart","Bach"] -- --------------------------------------------------------------------- musicos' :: [(String,String,Int,Int)] -> [String] musicos' bd = seleccion bd "Musica" -- --------------------------------------------------------------------- -- Ejercicio 16.5. Definir la función -- vivas :: [(String,String,Int,Int)] -> Int -> [String] -- tal que (vivas bd a) es la lista de los nombres de las personas de la -- base de datos bd que estaban vivas en el año a. Por ejemplo, -- ghci> vivas personas 1600 -- ["Cervantes","Velazquez","Quevedo","Borromini"] -- --------------------------------------------------------------------- vivas :: [(String,String,Int,Int)] -> Int -> [String] vivas ps a = [x | (x,_,a1,a2) <- ps, a1 <= a, a <= a2] |