==== Soluciones a los ejercicios de los parcialitos de la segunda parte del taller ==== === Recursión simple === * Definir la función **masLargasQue**, //masLargasQue :: Int -> [ [a] ] -> [ [a] ]//, que dado un natural //n// y una lista de listas, devuelve las listas que tienen más de //n// elementos. Ejemplo: masLargasQue 2 [ [1,2,3],[],[2,3] ] = [ [1,2,3] ]. Casos de Test: 0 y [ [67],[9] ], 8 y [ [] ]. **Solución 1** masLargasQue :: Int -> [[a]] -> [[a]] masLargasQue n [] = [] masLargasQue n (xs:xss) | length xs > n = xs : masLargasQue n xss | otherwise = masLargasQue n xss **Solución 2** masLargasQue' :: Int -> [[a]] -> [[a]] masLargasQue' n xs = filter (masLarga n) xs where masLarga :: Int -> [a] -> Bool masLarga n xs = n < length xs * Definir la función **sumaLongitud**, //sumaLongitud:: [Int] -> [Int]//, que dada una lista de enteros //xs//, devuelve una lista donde se ha sumado la longitud de //xs// a cada uno de los elementos de //xs//. Ejemplo: sumaLongitud [1,2,3] = [4,5,6], sumaLongitud [6,7] = [8,9]. Casos de Test: [], [2,-8,67]. **Solución 1** sumaLongitud :: [Int] -> [Int] sumaLongitud xs = map (+ length xs) xs **Solución 2** sumaLongitud' :: [Int] -> [Int] sumaLongitud' xs = sL (length xs) xs where sL :: Int -> [Int] -> [Int] sL n [] = [] sL n (x:xs) = x+n : sL xs === Para usar con generalizaciones === * Usando //map, filter// y //foldr//, definir la función **sumaTriplePares**, //sumaTriplePares :: [Int] -> Int//, que dada una lista de enteros //xs//, devuelve la suma de los números pares de //xs// multiplicados por 3. Ejemplo: sumaTriplePares [1,2,3,4,5,6] = 36. Casos de Test: [], [13,7,9], [12,45,6,86,7]. **Solución 1** sumaTriplePares :: [Int] -> Int sumaTriplePares xs = foldr (+) 0 (map (*3) (filter esPar xs) ) where esPar :: Int -> Bool esPar x = mod x 2 == 0 **Solución 2** sumaTriplePares' :: [Int] -> Int sumaTriplePares' xs = ( foldr (+) 0 (filter esPar xs) ) * 3 where esPar :: Int -> Bool esPar x = mod x 2 == 0 * Usando //map, filter// y //foldr//, definir la función **aprobadosSonPares**, //aprobadosSonPares:: [(String,Int)] -> Bool//, que dada una lista de tuplas //(String,Int)//, que se corresponden con el nombre y la nota de los estudiantes de la materia Algoritmos I, determina si los estudiantes que aprobaron la materia (con una nota de más de 4) se pueden agrupar en grupos de dos, es decir, devuelve True si el número de estudiantes que aprobaron la materia es par. Ejemplo: aprobadosSonPares [("Ana",5),("Pepe",6),("Juan",3),("Ester",8)] = False. Casos de Test: [], [("Ana",5),("Pepe",1),("Juan",3),("Ester",8)], [("Juan",3),("Ester",8)]. **Solución 1** aprobadosSonPares :: [(String,Int)] -> Bool aprobadosSonPares = esPar length (filter aprobo xs) where esPar :: Int -> Bool esPar x = mod x 2 == 0 aprobo :: (String,Int) -> Bool aprobo (_,x) = x > 4 **Solución 2** aprobadosSonPares' :: [(String,Int)] -> Bool aprobadosSonPares' = mod ( foldr (+) 0 (map sea1 (filter aprobo xs) ) ) 2 == 0 where sea1 :: a -> Bool sea1 x = 1 aprobo :: (String,Int) -> Bool aprobo (_,x) = x > 4 === Recursión en dos argumentos === * Definir la función **empiezanIgual**, //empiezanIgual:: Eq a => [a] -> [a] -> Bool//, que dadas dos listas //xs//, //ys//, decide si //xs// es el prefijo de //ys// o son iguales, es decir, si //ys// empieza con //xs// o bien si //ys// y //xs// son iguales. Ejemplos: empiezanIgual [3,4,5] [3,4,5,6] = True , empiezanIgual [3,4,5] [3,4,5] = True, empiezanIgual [3,4,5,6] [3,4,5] = False. Casos de Test: [] y ['a','b','c'], [89,56,7] y [4,53,3], [ [] ] y []. **Solución 1** empiezanIgual:: Eq a => [a] -> [a] -> Bool empiezanIgual (x:xs) (y:ys) = x==y && empiezanIgual xs ys empiezanIgual [] _ = True empiezanIgual _ [] = False * Definir la función **abrocharParidades**, //abrocharParidades :: [Int] -> [Int] -> [(Int,Int)]//, que, dadas dos listas, devuelve una lista de tuplas donde cada tupla contiene un elemento de la primera lista y un elemento de la segunda, de la siguiente forma: la primera tupla contiene el primer elemento de la primera lista y el primer elemento de la segunda lista, la segunda tupla contiene el segundo elemento de la primera lista y el segundo elemento de la segunda lista, etc. Pero atención: las tuplas sólo se arman si los elementos de la tupla, uno de cada lista, cumplen los siguientes requisitos: o bien los dos son pares o bien los dos son impares. Por ejemplo, si en la tercera posición de la primera lista hay un elemento par y en la tercera posición de la segunda lista hay un elemento impar, entonces no se arma esa tupla, sino que se ignora esa tupla y se sigue procesando el resto. Ejemplo: abrocharParidades [2,4,6,7,8] [12,16,15,19,21] = [(2,12),(4,16),(7,19)]. Casos de Test: [] y [2,3,4,5], [2,3,4,5] y [], [1,2,3,4] y [5,6,7,8]. **Solución 1** abrocharParidades :: [Int] -> [Int] -> [(Int,Int)] abrocharParidades (x:xs) (y:ys) | mod x 2 == 0 && mod y 2 == 0 = (x,y) : abrocharParidades xs ys | mod x 2 == 1 && mod y 2 == 1 = (x,y) : abrocharParidades xs ys | otherwise = abrocharParidades xs ys abrocharParidades _ _ = [] **Solución 2** abrocharParidades' :: [Int] -> [Int] -> [(Int,Int)] abrocharParidades' (x:xs) (y:ys) | mod (x+y) 2 == 0 = (x,y) : abrocharParidades xs ys | otherwise = abrocharParidades xs ys abrocharParidades' _ _ = []