Cursosā€Ž > ā€ŽCursadas Anterioresā€Ž > ā€Ž2014ā€Ž > ā€ŽMaƱ-SĆ”badoā€Ž > ā€Ž

TP Funcional 2

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.

  1. Dada una tupla de niveles definir las funciones:
    1. sumaNiveles, que suma todos los niveles
    2. diferenciaNiveles, es la diferencia entre el nivel mƔs alto y el nivel mƔs bajo.

  2. Dada una tupla persona definir las funciones
    1. sumaNivelesPersona, por ejemplo la suma de niveles de Harry es 20 (11+5+4).
      > sumaNivelesPersona ("Harry",(11, 5, 4))
      20

    2. diferenciaNivelesPersona, que aplicada a Harry deberĆ­a ser 7 (11 - 4).
      > diferenciaNivelesPersona ("Harry",(11, 5, 4))
      7

  3. 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

  4. 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"]


    1. 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

    2. 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.

  5. 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.

  6. 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.

  7. 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.


    1. 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.

    2. Escribir consultas que, usando la función del punto anterior, respondan la persona que quedó mÔs afectada según las siguientes solicitadas.

      1. suma de niveles (suerte, poder de convencimiento y fuerza fĆ­sica)
      2. promedio de niveles (puede ser el promedio entero)
      3. fuerza fĆ­sica
      4. 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.