Paradigma Funcional - TP 2
CLASE DE POCIONES
Se pide desarrollar un programa Haskell que ayude a analizar las pociones que se enseƱan a los alumnos en el colegioĀ Hogwarts de Magia y HechicerĆa, y los efectos que pueden hacer sobre personas.
Estas son algunas funciones ya definidas:
aplicar3 f (a,b,c) = (f a, f b, f c)
invertir3 (a,b,c) = (c,b,a)
fst3 (a,_,_) = a
snd3 (_,b,_) = b
trd3 (_,_,c) = c
sinRepetidos [] = []
sinRepetidos (x:xs)
Ā Ā Ā | elem x xs = sinRepetidos xs
Ā Ā Ā | otherwise = x : sinRepetidos xs
La información con la que se trabajarĆ” es la siguiente:Ā
personas =Ā [("Harry",(11, 5, 4)), ("Ron",(6,4,6)), ("Hermione",(8,12,2)), ("Draco",(7,9,6))]
Donde cada tupla de la lista tiene la forma:Ā ("Nombre del mago o bruja", (nivelSuerte, nivelPoderDeConvencimiento, nivelFuerzaFisica) )
f1 (ns,nc,nf) = (ns+1,nc+2,nf+3)
f2 = aplicar3 (max 7)
f3 (ns,nc,nf)
Ā Ā Ā | ns >= 8 = (ns,nc,nf+5)
Ā Ā Ā | otherwise = (ns,nc,nf-3)
misPociones = [
Ā Ā Ā ("Felix Felices",[
Ā Ā Ā Ā Ā Ā ("Escarabajos Machacados",52,[f1,f2]),
Ā Ā Ā Ā Ā Ā ("Ojo de Tigre Sucio",2,[f3])]),Ā
Ā Ā Ā ("Multijugos",[
Ā Ā Ā Ā Ā Ā ("Cuerno de Bicornio en Polvo",10, [invertir3, (\(a,b,c) -> (a,a,c))]),
Ā Ā Ā Ā Ā Ā ("Sanguijuela hormonal",54,[(aplicar3 (*2)), (\(a,b,c)Ā ->Ā (a,a,c))Ā ])]),
Ā Ā Ā ("Flores de Bach",[
Ā Ā Ā Ā Ā Ā ("Orquidea Salvaje",8,[f3]),Ā
Ā Ā Ā Ā Ā Ā ("Rosita",1,[f1])])Ā
Ā Ā Ā ]
Donde cada tupla poción de la lista tiene la forma: ("Nombre de la Pocion", [ ("NombreIngrediente", cantidadEnGramos, [efecto] ) ] )
Los efectos son funciones que reciben una 3-upla de niveles (nivelSuerte, nivelPoderDeConvencimiento,Ā nivelFuerzaFisica) y devuelven otra 3-upla con alguno o todos los niveles cambiados.
A partir de la base de conocimiento presentada, se pide resolver los siguientes puntos utilizando los conceptos aprendidos del paradigma funcional: composición, aplicación parcial, orden superior, listas por comprensión.
- Dada una tupla de niveles definir las funciones:
- sumaNiveles, que suma todos los niveles
- diferenciaNiveles, es la diferencia entre el nivel mƔs alto y el nivel mƔs bajo.
- Dada una tupla persona definir las funciones
- sumaNivelesPersona, por ejemplo la suma de niveles de Harry es 20 (11+5+4).
> sumaNivelesPersona ("Harry",(11, 5, 4))
20
- diferenciaNivelesPersona, que aplicada a Harry deberĆa ser 7 (11 - 4).
> diferenciaNivelesPersona ("Harry",(11, 5, 4))
7
- Definir la función efectosDePocion, que recibe una tupla poción y devuelve una lista con todos los efectos de cada uno de sus ingredientes. Si tuvieramos una poción definida por la siguiente función constante:
pocionFelix =Ā ("Felix Felices",[("Escarabajos Machacados", 52, [f1,f2]),("Ojo de tigre sucio",2,[f3])])
Los efectos de la misma serĆan:
> efectosDePocionĀ pocionFelix
[f1,f2,f3]
NOTA: En Haskell las funciones no se pueden mostrar, esto es solo una consulta a modo de ejemplo. Intentar la consulta directamente como se muestra en el ejemplo resultarĆa en un error. Sus pruebas para este punto las van a tener que armar usando la función del punto 7 y definiendo sus propias pociones con efectos sencillos para comprobar los resultados
- Definir la función pocionesHeavies, que recibe una lista de pociones y devuelve los nombres de las pociones que tienen al menos 4 efectos.
> pocionesHeavies misPociones
["Multijugos"]
- definir la funcion incluyeA que espera dos listas, devolviendo True si la primera estĆ” incluida en la segunda. Por ejemplo:
> incluyeA [3,6,9] [1..10]Ā
True
- definir la función esPocionMagica. Una poción es mÔgica si el nombre de alguno de sus ingredientes tiene todas las vocales y ademÔs de todos los ingredientes se pide una cantidad par.
En el ejemplo āMultijugosā es mĆ”gica, āFelix Felicesā no porque ningĆŗn nombre incluye todas las vocales, āFlores deĀ Bachā no porque hay un ingrediente con cantidad impar.
- Definir la funciónĀ maximoSegun, que dadas una función y una lista de valores obtiene aquel valor de la lista que maximiza el resultado de la función.Ā
NOTA: No se puede usar recursividad.
- Definir la función tomarPocion, que recibe una poción y una persona, y devuelve una tupla persona que muestraĀ cómo quedarĆa la persona despuĆ©s de haber tomado la poción.
Cuando una persona se toma una poción, se le aplican todos los efectos de cada ingrediente de la poción, en orden. Siendo pocionFelix la misma función constante de ejemplo que en el punto 1:
El efecto producido por esta poción en Harry Potter serĆa:
> tomarPocion pocionFelix ("Harry",(11, 5, 4))
("Harry", (12, 7, 12))
Porque le aplica f1, f2 y por Ćŗltimo f3
NOTA: Resolver la función en dos versiones: una que aplique fold (en alguna de sus versiones) y otra recursiva.
- Definir la función esAntidoto, que recibe una persona y dos pociones, y devuelve true en caso de que la segunda poción revierta el efecto de la primera sobre la persona. Es decir, si la persona queda igual después de tomar primero la primer poción y después la segunda.
- Definir la función personaMasAfectada, que recibe una poción, unaĀ ponderaciónĀ de niveles y una lista de personas, yĀ devuelve la persona que despuĆ©s de tomarse la poción hace mĆ”ximo el valor de la ponderación de niveles.Ā Una ponderación de niveles es una función que espera una terna de niveles (suerte,convencimiento,fuerza fĆsica) yĀ devuelve un nĆŗmero.
NOTA: No se puede usar recursividad, listas por comprensión, foldl ni definiciones locales.
- Escribir consultas que, usando la función del punto anterior, respondan la persona que quedó mÔs afectada según las siguientes solicitadas.
- suma de niveles (suerte, poder de convencimiento y fuerza fĆsica)
- promedio de niveles (puede ser el promedio entero)
- fuerza fĆsica
- diferencia de niveles
NOTA:Ā No se pueden crear nuevas funcionesĀ para este punto. Se deben resolver todas las consultas aplicando las funciones de puntos anteriores y/o del Prelude de Haskell.