introalg:taller09_soluciones
Diferencias
Muestra las diferencias entre dos versiones de la página.
Próxima revisión | Revisión previa | ||
introalg:taller09_soluciones [2009/04/05 23:33] – creado laura | introalg:taller09_soluciones [2018/08/10 03:03] (actual) – editor externo 127.0.0.1 | ||
---|---|---|---|
Línea 1: | Línea 1: | ||
+ | =====Soluciones a ejercicios===== | ||
+ | |||
+ | ====ejercicios de prolog, 30/ | ||
+ | |||
+ | ===familia=== | ||
+ | |||
< | < | ||
%%%%%%%%%%%% | %%%%%%%%%%%% | ||
Línea 54: | Línea 60: | ||
hijoúnico(X) :- not(hermano(_, | hijoúnico(X) :- not(hermano(_, | ||
</ | </ | ||
+ | |||
+ | Otra opción para hijo único que funciona mejor, más acorde a nuestras intuiciones sobre el concepto: | ||
+ | |||
+ | < | ||
+ | hijoúnico(X) :- ( hombre(X) ; mujer(X) ) , ( not(hermano(_, | ||
+ | </ | ||
+ | |||
+ | Esta opción funciona mejor porque el árbol de búsqueda de resultados que se arma y sobre el cual el intérprete hace backtracking es considerablemente distinto. | ||
+ | |||
+ | ====ejercicios de prolog, 6/04/09==== | ||
+ | |||
+ | ===extensión de familia=== | ||
+ | |||
+ | Incorporamos cuñados, suegras y demás familias políticas. Para ello nos resultará muy útil definir el predicado " | ||
+ | |||
+ | < | ||
+ | pareja(X,Y) :- progenitor(X, | ||
+ | |||
+ | cuñado(X, | ||
+ | cuñada(X, | ||
+ | suegra(X,Y) :- madre(X,Z), pareja(Y, | ||
+ | suegro(X,Y) :- padre(X,Z), pareja(Y, | ||
+ | </ | ||
+ | |||
+ | Fíjense que no hay que explicitar el sexo del cuñado, suegra, etc. porque ya está implícito en los predicados " | ||
+ | |||
+ | Para incorporar la regla " | ||
+ | |||
+ | < | ||
+ | %%% declaramos hechos sobre la edad de algunos miembros de la familia %%% | ||
+ | edad(lucía, | ||
+ | edad(blanca, | ||
+ | edad(mario, | ||
+ | |||
+ | mayor(X,Y) :- edad(X,EX), edad(Y,EY), EX>EY. | ||
+ | |||
+ | hermanoMayor(X, | ||
+ | hermanoMenor(X, | ||
+ | hermanaMayor(X, | ||
+ | hermanaMenor(X, | ||
+ | </ | ||
+ | |||
+ | ====ejercicios de haskell, 13/ | ||
+ | |||
+ | * '' | ||
+ | < | ||
+ | ordena :: (Int,Int) -> (Int,Int) | ||
+ | ordena (x,y) | x < y = (x,y) | ||
+ | | ||
+ | | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | ordena' | ||
+ | ordena' | ||
+ | | x > y = (y,x) | ||
+ | </ | ||
+ | |||
+ | * '' | ||
+ | < | ||
+ | ambospositivos :: Int -> Int -> Bool | ||
+ | ambospositivos x y | x >= 0 && y >= 0 = True | ||
+ | | x >= 0 || y < 0 = False | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | ambospositivos'' | ||
+ | ambospositivos'' | ||
+ | </ | ||
+ | |||
+ | * '' | ||
+ | < | ||
+ | edad :: (Int, Int, Int) -> (Int, Int, Int) -> Int | ||
+ | edad (diaN, | ||
+ | | otherwise | ||
+ | </ | ||
+ | |||
+ | * '' | ||
+ | < | ||
+ | cabeza :: [a] -> a | ||
+ | cabeza (x:_) = x | ||
+ | cabeza [] = error "la lista es vacía y por lo tanto no tiene cabeza!" | ||
+ | </ | ||
+ | |||
+ | * '' | ||
+ | < | ||
+ | cola :: [a] -> [a] | ||
+ | cola (_:xs) = xs | ||
+ | cola [] = [] | ||
+ | </ | ||
+ | |||
+ | * Definición del área de un prisma. | ||
+ | < | ||
+ | area :: Int -> Int -> Int -> Int | ||
+ | area alto ancho fondo = 2*frente + 2*lado + 2*tapa | ||
+ | where | ||
+ | frente = alto * ancho | ||
+ | lado = alto * fondo | ||
+ | tapa = ancho * fondo | ||
+ | </ | ||
+ | |||
+ | * '' | ||
+ | < | ||
+ | esVaciaOPrimer0 :: [Int] -> Bool | ||
+ | esVaciaOPrimer0 [] = True | ||
+ | esVaciaOPrimer0 (x:_) | x == 0 = True | ||
+ | | otherwise = False | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | esVaciaOPrimer0' | ||
+ | esVaciaOPrimer0' | ||
+ | esVaciaOPrimer0' | ||
+ | </ | ||
+ | |||
+ | * '' | ||
+ | < | ||
+ | segundoEsSegundo :: (Int,Int) -> [Int] -> Bool | ||
+ | segundoEsSegundo (_,x) (_:y:_) = x == y | ||
+ | </ | ||
+ | |||
+ | * '' | ||
+ | < | ||
+ | recortaDia :: [Char] -> [Char] | ||
+ | recortaDia x:xs | (x:xs) == " | ||
+ | | (x:xs) == " | ||
+ | | otherwise = error "el string de entrada no es un dia de la semana o tiene mayusculas o acentos" | ||
+ | |||
+ | </ | ||
+ | |||
+ | ====ejercicios de haskell, 20/ | ||
+ | |||
+ | '' | ||
+ | < | ||
+ | averaver :: (Int, | ||
+ | averaver x y z | x > 0 && y > 0 && z > 0 = (z,y,x) | ||
+ | | x < 0 && y < 0 && z < 0 = ((-x), | ||
+ | | otherwise | ||
+ | </ | ||
+ | |||
+ | '' | ||
+ | < | ||
+ | ordenaSiPositivos :: (Int,Int) -> (Int,Int) | ||
+ | ordenaSiPositivos (x,y) | x > 0 && y > 0 && x <= y = (x,y) | ||
+ | | x > 0 && y > 0 = (y,x) | ||
+ | | otherwise | ||
+ | </ | ||
+ | |||
+ | o podemos colapsar los casos que tienen el mismo resultado: | ||
+ | < | ||
+ | ordenaSiPositivos' | ||
+ | ordenaSiPositivos' | ||
+ | | otherwise | ||
+ | </ | ||
+ | |||
+ | |||
+ | ====ejercicios de haskell, 27/ | ||
+ | |||
+ | '' | ||
+ | < | ||
+ | veintePorCiento :: [Float] -> [Float] | ||
+ | veintePorCiento [] = [] | ||
+ | veintePorCiento (x:xs) = 0.2*x : veintePorCiento xs | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | porCiento :: Float -> [Float] -> [Float] | ||
+ | porCiento n [] = [] | ||
+ | porCiento n (x:xs) = n/100*x : porCiento n xs | ||
+ | </ | ||
+ | |||
+ | '' | ||
+ | < | ||
+ | multiplicar :: Int -> [Int] -> [Int] | ||
+ | multiplicar n [] = [] | ||
+ | multiplicar n (x:xs) = n*x : multiplicar n xs | ||
+ | </ | ||
+ | |||
+ | '' | ||
+ | < | ||
+ | soloPares :: [Int] -> [Int] | ||
+ | soloPares [] = [] | ||
+ | soloPares (x:xs) | mod x 2 == 0 = x : soloPares xs | ||
+ | | otherwise | ||
+ | |||
+ | </ | ||
+ | |||
+ | '' | ||
+ | < | ||
+ | ningunFalse :: [Bool] -> [Bool] | ||
+ | ningunFalse [] = [] | ||
+ | ningunFalse (x:xs) | x == True = x : ningunFalse xs | ||
+ | | otherwise = | ||
+ | </ | ||
+ | |||
+ | '' | ||
+ | < | ||
+ | soloMultiplos3 :: [Int] -> [Int] | ||
+ | soloMultiplos3 [] = [] | ||
+ | soloMultiplos3 (x:xs) | mod x 3 == 0 = x : soloMultiplos3 xs | ||
+ | | otherwise | ||
+ | </ | ||
+ | |||
+ | '' | ||
+ | < | ||
+ | productoria :: [Int] -> Int | ||
+ | productoria [] = 1 | ||
+ | productoria (x:xs) = x * productoria xs | ||
+ | </ | ||
+ | |||
+ | '' | ||
+ | < | ||
+ | longitud :: [Int] -> Int | ||
+ | longitud [] = 0 | ||
+ | longitud (x:xs) = 1 + longitud xs | ||
+ | </ | ||
+ | |||
+ | '' | ||
+ | < | ||
+ | sonTodos0 :: [Int] -> Bool | ||
+ | sonTodos0 [] = True | ||
+ | sonTodos0 (x:xs) = x == 0 && sonTodos0 xs | ||
+ | </ | ||
+ | |||
+ | '' | ||
+ | < | ||
+ | todos0y1 :: [Int] -> Bool | ||
+ | todos0y1 [] = True | ||
+ | todos0y1 (x:xs) = ( x==0 || x==1 ) && todos0y1 xs | ||
+ | </ | ||
+ | |||
+ | '' | ||
+ | < | ||
+ | paratodo :: Eq a => a -> [a] -> Bool | ||
+ | paratodo e [] = True | ||
+ | paratodo e (x:xs) = e == x && paratodo e xs | ||
+ | </ | ||
+ | Fíjense que tenemos que añadir a la signatura el preámbulo '' | ||
+ | |||
+ | '' | ||
+ | < | ||
+ | hayun0 :: [Int] -> Bool | ||
+ | hayun0 [] = False | ||
+ | hayun0 (x:xs) = x == 0 || hayun0 xs | ||
+ | </ | ||
+ | |||
+ | '' | ||
+ | < | ||
+ | existe :: a -> [a] -> Bool | ||
+ | existe e [] = False | ||
+ | existe e (x:xs) = e == x || existe e xs | ||
+ | </ | ||
+ | |||
+ | Escribir la función que calcula la Sucesión de Fibonacci, '' | ||
+ | < | ||
+ | fib :: Int -> Int | ||
+ | fib 0 = 0 | ||
+ | fib 1 = 1 | ||
+ | fib n+2 = fib (n+1) + fib n | ||
+ | </ | ||
+ | |||
+ | '' | ||
+ | < | ||
+ | sumaPares :: [(Int, Int)] -> Int | ||
+ | sumaPares [] = 0 | ||
+ | sumaPares ((x,y):xs) = x + y + sumaPares xs | ||
+ | </ | ||
+ | |||
+ | '' | ||
+ | < | ||
+ | repetir :: Int -> a -> [a] | ||
+ | repetir 0 a = [] | ||
+ | repetir n a = a : repetir (n-1) a | ||
+ | </ | ||
+ | |||
+ | '' | ||
+ | < | ||
+ | esMultiploLista :: Int -> [Int] -> [Bool] | ||
+ | esMultiploLista n [] = [] | ||
+ | esMultiploLista n (x:xs) = mod n x == 0 : esMultiploLista n xs | ||
+ | </ | ||
+ | |||
+ | |||
+ | === Miscelánea un poco más complicada === | ||
+ | |||
+ | '' | ||
+ | < | ||
+ | sumaPares :: [Int] -> Int | ||
+ | sumaPares [] = 0 | ||
+ | sumaPares (x:xs) | mod x 2 == 0 = x + sumaPares xs | ||
+ | | otherwise | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | sumaPares' | ||
+ | sumaPares' | ||
+ | </ | ||
+ | |||
+ | '' | ||
+ | < | ||
+ | estudiantesMayores35 :: [(String, | ||
+ | estudiantesMayores35 [] = 0 | ||
+ | estudiantesMayores35 ((n, | ||
+ | | otherwise | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | estudiantesMayores35' | ||
+ | estudiantesMayores35' | ||
+ | |||
+ | mayores35 :: [(String, | ||
+ | mayores35 [] = [] | ||
+ | mayores35 ((n, | ||
+ | | otherwise | ||
+ | </ | ||
+ | |||
+ | '' | ||
+ | < | ||
+ | listaMayorQue :: Int -> [[a]] -> Bool | ||
+ | listaMayorQue n [] = True | ||
+ | listaMayorQue n (x:xs) = n <= (longitud x) && listaMayorQue n xs | ||
+ | </ | ||
+ | |||
+ | '' | ||
+ | < | ||
+ | totalSueldos :: [Float] -> Float | ||
+ | totalSueldos [] = 0 | ||
+ | totalSueldos (x:xs) = porCiento 5 x + x + totalSueldos xs | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | totalSueldos' | ||
+ | totalSueldos' | ||
+ | |||
+ | incrementaPorCiento :: Float -> [Float] -> [Float] | ||
+ | incrementaPorCiento n [] = [] | ||
+ | incrementaPorCiento n (x:xs) = porCiento n x + x : incrementaPorCiento n xs | ||
+ | </ | ||
+ | |||
+ | '' | ||
+ | < | ||
+ | impuestoLujo :: [(String, | ||
+ | impuestoLujo [] = [] | ||
+ | impuestoLujo ((n,x):xs) | x > 10000 = (n, | ||
+ | | otherwise = (n,x) : impuestoLujo xs | ||
+ | </ | ||
+ | |||
+ | '' | ||
+ | < | ||
+ | cuentaInteresantes :: [(String, | ||
+ | cuentaInteresantes [] = 0 | ||
+ | cuentaInteresantes ((x,y):xs) | y == True = 1 + cuentaInteresantes xs | ||
+ | | otherwise = | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | cuentaInteresantes' | ||
+ | cuentaInteresantes' | ||
+ | |||
+ | interesantes :: [(String, | ||
+ | interesantes [] = [] | ||
+ | interesantes ((x,y):xs) | y == True = x : cuentaInteresantes xs | ||
+ | | otherwise = | ||
+ | </ | ||
+ | |||
+ | '' | ||
+ | < | ||
+ | edadPromedio :: [(String, | ||
+ | edadPromedio xs = (sumatoriaSegundo xs) / (longitud xs) | ||
+ | |||
+ | sumatoriaSegundo :: [(String, | ||
+ | sumatoriaSegundo [] = 0 | ||
+ | sumatoriaSegundo ((x,y):xs) = y + sumatoriaSegundo xs | ||
+ | </ | ||
+ | |||
+ | ====ejercicios de haskell, 5/05/09==== | ||
+ | |||
+ | A partir de la siguiente base de conocimiento en prolog, crear las reglas necesarias para que el intérprete nos diga si una persona alérgica a la frutilla puede comer helado de frutilla: | ||
+ | < | ||
+ | esAlérgico(pepe, | ||
+ | esAlérgico(juan, | ||
+ | esAlérgico(maría, | ||
+ | |||
+ | tiene(helado, | ||
+ | tiene(torta, | ||
+ | </ | ||
+ | Creamos la regla: | ||
+ | < | ||
+ | puedeComer(X, | ||
+ | ( esAlérgico(X, | ||
+ | ( not(esAlérgico(X, | ||
+ | </ | ||
+ | |||
+ | A partir de la siguiente base de conocimiento en prolog, crear las reglas necesarias para que el intérprete nos diga qué alimento puede comer cada animal: | ||
+ | < | ||
+ | herbívoro(vaca). | ||
+ | herbívoro(oveja). | ||
+ | carnívoro(león). | ||
+ | hortaliza(tomate). | ||
+ | hortaliza(zanahoria). | ||
+ | fruta(manzana). | ||
+ | pescado(besugo). | ||
+ | carne(salchicha). | ||
+ | fideos(spaghetti). | ||
+ | </ | ||
+ | Creamos las reglas: | ||
+ | < | ||
+ | planta(X) :- hortaliza(X) ; fruta(X) ; fideos(X). | ||
+ | animal(X) :- carne(X) ; pescado(X) ; herbívoro(X) ; carnívoro(X). | ||
+ | |||
+ | come(X,Y) :- | ||
+ | ( herbívoro(X) , planta(Y) ) ; | ||
+ | ( carnívoro(X) , animal(Y) ) . | ||
+ | </ | ||
+ | |||
+ | '' | ||
+ | < | ||
+ | soloEntre0y9 :: [Int] -> [Int] | ||
+ | soloEntre0y9 [] = [] | ||
+ | soloEntre0y9 (x:xs) | 0 <= x && x <= 9 = x : soloEntre0y9 xs | ||
+ | | otherwise | ||
+ | </ | ||
+ | |||
+ | |||
+ | '' | ||
+ | < | ||
+ | sumatoriaEsPar :: [Int] -> Bool | ||
+ | sumatoriaEsPar xs = mod (sumatoria xs) 2 == 0 | ||
+ | </ | ||
+ | |||
+ | '' | ||
+ | < | ||
+ | cuantos0 :: [Int] -> Int | ||
+ | cuantos0 xs = longitud (solo 0 xs) | ||
+ | |||
+ | solo :: Eq a => a -> [a] -> [a] | ||
+ | solo e [] = [] | ||
+ | solo e (x:xs) | e == x = x : solo e xs | ||
+ | | otherwise = solo e xs | ||
+ | </ | ||
+ | |||
+ | '' | ||
+ | < | ||
+ | paresHasta :: Int -> [Int] | ||
+ | paresHasta n = paresHasta' | ||
+ | |||
+ | paresHasta' | ||
+ | paresHasta' | ||
+ | | otherwise = m : paresHasta' | ||
+ | </ | ||
+ | |||
+ | |||
+ | ===Ejercicios de recursión en dos argumentos=== | ||
+ | |||
+ | '' | ||
+ | < | ||
+ | iguales :: Eq a => [a] -> [a] -> Bool | ||
+ | iguales [] [] = True | ||
+ | iguales (x:xs) (y:ys) = x == y && iguales xs ys | ||
+ | </ | ||
+ | |||
+ | '' | ||
+ | < | ||
+ | encuentraEstafador' | ||
+ | encuentraEstafador' | ||
+ | encuentraEstafador' | ||
+ | encuentraEstafador' | ||
+ | encuentraEstafador' | ||
+ | | x < y = encuentraEstafador' | ||
+ | | x == y = x : encuentraEstafador' | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | encuentraEstafador'' | ||
+ | encuentraEstafador'' | ||
+ | | x < y = encuentraEstafador'' | ||
+ | | x == y = x : encuentraEstafador'' | ||
+ | encuentraEstafador'' | ||
+ | </ | ||
+ | |||
+ | |||
+ | ====ejercicios de haskell, alto orden ==== | ||
+ | |||
+ | '' | ||
+ | < | ||
+ | cuantosCumplen :: (Int -> Bool) -> [Int] -> Int | ||
+ | cuantosCumplen p [] = 0 | ||
+ | cuantosCumplen p (x:xs) | p x = 1 + cuantosCumplen p xs | ||
+ | | otherwise = | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | cuantosCumplen' | ||
+ | cuantosCumplen' | ||
+ | </ | ||
+ | |||
+ | ==== ejercicios de haskell 18/05/2009: aplicando generalizaciones ==== | ||
+ | |||
+ | Redefinir todos los ejercicios recursivos en listas propuestos en las clases anteriores aplicando las generalizaciones '' | ||
+ | |||
+ | |||
+ | ==== ejercicios de prolog 18/05/2009: más recursividad ==== | ||
+ | |||
+ | * Definan una función que determine si Clara es mayor que Elena, dada la siguiente base de conocimiento: | ||
+ | < | ||
+ | mayor(clara, | ||
+ | mayor(esteban, | ||
+ | mayor(paula, | ||
+ | mayor(marcos, | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | mayorQue(X, | ||
+ | mayorQue(X, | ||
+ | </ | ||
+ | |||
+ | * Tenemos una lista de las conexiones por tren entre pares de ciudades, por ejemplo '' | ||
+ | |||
+ | ==== ejercicios sobre la vida real 1/06/2009 ==== | ||
+ | |||
+ | Encontrarán una posible solución al problema de recomendar amigos en una red social tipo // | ||
+ | |||
+ | También damos una posible solución al problema de calcular el porcentaje de estudiantes que aprueban o promocionan la materia en la [[http:// | ||
+ | |||
+ | * Comprobar si podemos cocinar un determinado platillo dados los ingredientes necesarios para el platillo y los ingredientes que tenemos en la heladera. Se puede ampliar con los utensilios, las técnicas, e implicaciones entre ellos (p.ej., si tenemos que usar la técnica " | ||
+ | < | ||
+ | ingredientes(tortilla, | ||
+ | ingredientes(papafrita, | ||
+ | ingredientes(huevofrito, | ||
+ | ingredientes(pizza, | ||
+ | ingredientes(asado, | ||
+ | ingredientes(crema, | ||
+ | |||
+ | tengo(sal). | ||
+ | tengo(azúcar). | ||
+ | tengo(pimienta). | ||
+ | tengo(canela). | ||
+ | tengo(huevos). | ||
+ | tengo(leche). | ||
+ | tengo(queso). | ||
+ | tengo(maicena). | ||
+ | |||
+ | puedoCocinar(Platillo) :- | ||
+ | | ||
+ | | ||
+ | |||
+ | tengoTodos([]). | ||
+ | tengoTodos([I|Ingredientes]) :- tengo(I) , tengoTodos(Ingredientes). | ||
+ | </ | ||
+ | |||
+ | * Crear un sistema de alertas que cuando se consume un insumo, chequea en la base de datos cuánta reserva queda de ese insumo y, si la reserva está por debajo de un mínimo, devuelve un mensaje diciendo que hay que comprar más de ese insumo. | ||
+ | < | ||
+ | queda(jeringas, | ||
+ | queda(vendas, | ||
+ | queda(curitas, | ||
+ | |||
+ | minimo(jeringas, | ||
+ | minimo(vendas, | ||
+ | minimo(curitas, | ||
+ | |||
+ | bajoMinimo(Insumo, | ||
+ | queda(Insumo, | ||
+ | minimo(Insumo, | ||
+ | (Reserva - Cantidad) =< Minimo . | ||
+ | </ | ||
+ | |||
+ | * Hacer un programa **no muy largo** que, dado un animal, nos diga si es ovíparo o vivíparo, si vive en la tierra, en el agua o en el aire, si come carne o vegetales, etc. Tratar excepciones como " | ||
+ | < | ||
+ | mamifero(vaca). | ||
+ | mamifero(delfín). | ||
+ | mamifero(nutria). | ||
+ | acuatico(delfín). | ||
+ | acuatico(nutria). | ||
+ | pez(trucha). | ||
+ | pez(guppi). | ||
+ | viviparo(guppi). | ||
+ | |||
+ | terrestre(X) :- mamifero(X) , not(acuatico(X)). | ||
+ | acuatico(X) :- pez(X). | ||
+ | viviparo(X) :- mamifero(X). | ||
+ | oviparo(X) :- pez(X) , not(viviparo(X)). | ||
+ | </ | ||
+ | |||
+ | ==== ejercicios de recursividad clásicos 1/06/2009 ==== | ||
+ | |||
+ | El problema del máximo común divisor se soluciona muy fácilmente si por azar sabemos que hay una recetita maravillosa que dice así: dados dos números, si uno es divisor del otro, entonces ese será el máximo común divisor. Si no, se resta el número menor al mayor y volvemos a comprobar si uno es divisor del otro. Si no, se resta el menor al mayor, y así hasta llegar a algún caso en el que uno de los dos números sea divisor del otro. | ||
+ | < | ||
+ | mcd :: Int -> Int -> Int | ||
+ | mcd a b | mod a b == 0 = b | ||
+ | | mod b a == 0 = a | ||
+ | | otherwise | ||
+ | </ | ||
+ | |||
+ | El problema de las n reinas (perdón, no eran 9 :-} ). Está muy bien explicado en el [[http:// | ||
+ | |||
+ | El problema de misioneros y caníbales está bien explicado como caso particular de un problema de búsqueda en estas [[https:// |
introalg/taller09_soluciones.1238974418.txt.gz · Última modificación: 2018/08/10 03:03 (editor externo)