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

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