UTNianos

Versión completa: TP Funcional (Haskell)
Actualmente estas viendo una versión simplificada de nuestro contenido. Ver la versión completa con el formato correcto.
Páginas: 1 2
Buenas gente!
Estoy con un problema con unos ejercicios de Haskell, espero que alguno me pueda ayudar.

Es el punto 4:

Cita:4. Rutina de ejercicios:
a. Dada una rutina (tupla con un nombre, duración total y lista de ejercicios específicos) y una
persona, obtener a la persona luego de realizar la rutina. La cantidad de minutos dedicada a
cada ejercicio es la misma.
Mostrar un ejemplo de uso usando todos los ejercicios del punto anterior.
Resolver de dos formas:
● Con recursividad
● Con fold

Mi problema es que no se como pasarle una lista de funciones (rutinas) a una persona, mas aun cuando algunas de esas rutinas tienen argumentos adicionales (kilos, inclinacion, etc)

Dejo el enunciado adjunto como referencia.

Y acá esta lo que tengo hecho del TP hasta ahora:


type Nombre = String
type Edad = Float
type Peso = Float
type Tonificacion = Float

data Persona = Socio Nombre Edad Peso Tonificacion deriving Show

ana = (Socio "ana" 25.0 50.0 6.0)
andres = (Socio "andres" 30.0 120.0 1.0)
pancho = (Socio "francisco" 40.0 120.0 1.0)

--1
saludable :: Persona -> Bool
saludable persona = not (obeso persona) && tonificacion persona > 5.0

--2
quemarCalorias :: Float -> Persona -> Persona
quemarCalorias calorias persona | obeso persona = bajarDePeso (calorias/150.0) persona
| edad persona > 30.0 && calorias > 200.0 = bajarDePeso 1 persona
| otherwise = bajarDePeso (calorias / (peso persona * edad persona)) persona

--3
caminataEnCinta :: Float -> Persona -> Persona
caminataEnCinta minutos persona = quemarCalorias (5.0 * minutos) persona

entrenamientoEnCinta :: Float -> Persona -> Persona
entrenamientoEnCinta minutos persona = quemarCalorias (velocidadPromedio minutos * minutos) persona

pesas :: Float -> Float -> Persona -> Persona
pesas minutos kilos persona | minutos > 10.0 = aumentarTonificacion (kilos / 10.0) persona
| otherwise = persona

colina :: Float -> Float -> Persona -> Persona
colina minutos inclinacion persona = quemarCalorias (2.0 * minutos * inclinacion) persona

montana :: Float -> Float -> Persona -> Persona
montana minutos inclinacion persona = ((colina (minutos/2.0) inclinacion).(colina (minutos/2.0) (inclinacion+3.0)).(aumentarTonificacion 1.0)) persona


{-
4a
aplicarRutina :: (String, Float, [(Float -> Persona -> Persona)]) -> Persona -> Persona
aplicarRutina (nombreRutina, duracionRutina, ejercicios) persona = map (ejercicios (duracionRutina/length ejercicios)) persona

rutina = [caminataEnCinta, entrenamientoEnCinta] --, pesas , colina, montana llevan argumento adicional


4b
type Resumen = (Nombre, Peso, Tonificacion)

resumenRutina :: Rutina -> Persona -> Resumen
resumenRutina =

5
rutinasSaludables :: [Rutina] -> [Rutina]
rutinasSaludables =

6
???

-}

--Funciones Auxiliares
nombre (Socio nombre _ _ _) = nombre
edad (Socio _ edad _ _) = edad
peso (Socio _ _ peso _) = peso
tonificacion (Socio _ _ _ tonificacion) = tonificacion

obeso persona = peso persona > 100.0

bajarDePeso cantidad (Socio nombre edad peso tonificacion) = (Socio nombre edad (peso-cantidad) tonificacion)

velocidadPromedio :: Float -> Float
velocidadPromedio minutos = (velocidadMinima + velocidadMaxima minutos) / 2.0
velocidadMinima :: Float
velocidadMinima = 6.0
velocidadMaxima :: Float -> Float
velocidadMaxima minutos = 6.0 + minutos / 5.0

aumentarTonificacion cantidad (Socio nombre edad peso tonificacion) = (Socio nombre edad peso (tonificacion+cantidad))

--Pruebas

{-
Main> saludable ana
True

Main> saludable andres
False

Main> quemarCalorias 300 pancho
Socio "francisco" 40.0 118.0 1.0

Main> caminataEnCinta 40 pancho
Socio "francisco" 40.0 118.6667 1.0

Main> entrenamientoEnCinta 40 pancho
Socio "francisco" 40.0 117.3333 1.0

Main> pesas 50 15 pancho
Socio "francisco" 40.0 120.0 2.5

Main> colina 5 40 pancho
Socio "francisco" 40.0 117.3333 1.0

Main> montana 5 40 pancho
Socio "francisco" 40.0 117.2333 2.0
-}



Gracias!
1)
Tal vez, y sólo tal vez, no es una buena idea poner tu resolución de un ejercicio para que lo vea todo el mundo =P

2)
Aplicá parcialmente las funciones pesas, colina y montaña. O pasale parámetros extra a las otras funciones que no usen, para hacerlas del mismo tipo.
(29-04-2014 11:40)Ichiluk escribió: [ -> ]1)
Tal vez, y sólo tal vez, no es una buena idea poner tu resolución de un ejercicio para que lo vea todo el mundo =P
No creo que sea problema, al contrario, puede servirle de mucho a alguien que no entiende el tema, siempre teniendo en cuenta, que no está corregido y puede tener errores, por supuesto.

(29-04-2014 11:40)Ichiluk escribió: [ -> ]2)
Aplicá parcialmente las funciones pesas, colina y montaña. O pasale parámetros extra a las otras funciones que no usen, para hacerlas del mismo tipo.

Pasarles parametros extra a las otras funciones funcionaría, de hecho es la forma mas simple, pero me parece que estaría haciendo cosas que en PdeP llaman "poco felices" y "bajan el CFD".

Por ahora lo que hice es esto. Funciona bien para las funciones caminataEnCinta y entrenamientoEnCinta.
Me podrías aclarar como usar aplicación parcial para las funciones pesas, colina y montaña?

Gracias!!



type Rutina = (String, Float, [(Float -> Persona -> Persona)])

aplicarRutina :: Rutina -> Persona -> Persona
aplicarRutina (nombreRutina, duracionRutina, []) persona = persona
aplicarRutina (nombreRutina, duracionRutina, (ej:ejs)) persona = aplicarRutina (nombreRutina, duracionRutina, ejs) (ej duracionRutina persona)

rutina :: Rutina
rutina = ("rutina", 50.0, [caminataEnCinta, entrenamientoEnCinta]) --, pesas , colina, montana llevan argumento adicional



Main> aplicarRutina rutina pancho
Socio "francisco" 40.0 114.6667 1.0
Llegue al punto de My code works, I have no idea why

Ni dios sabe como pero a haskell le paso el argumento y se da cuenta de donde carajo tiene que meterlo



--4a
type Rutina = (String, Float, [(Float -> Persona -> Persona)])

rutina :: Rutina
rutina = ("rutina", 200.0, [caminataEnCinta, entrenamientoEnCinta, (pesas 100.0), (colina 20.0), (montana 50.0)]) --, pesas , colina, montana llevan argumento adicional

aplicarRutina :: Rutina -> Persona -> Persona
aplicarRutina (_, _, []) persona = persona
aplicarRutina (nombreRutina, duracionRutina, (ej:ejs)) persona = aplicarRutina (nombreRutina, duracionRutina, ejs) (ej duracionRutina persona)


Podés hacer que tu ejercicio sea por 10 minutos.

Entonces


hacerPesasPor10Minutos kilos persona = pesas 10.0 kilos persona


y

hacerPesasPor10Minutos :: Float -> Persona -> Persona


que es el mismo tipo que las anteriores.

Lo mismo con las otras funciones =)
Gracias por las sugerencias, pero dudo que se acepte eso, ya que estoy modificando otras funciones, las cuales son parte del enunciado.
Dejo el TP terminado (me falto hacer el 4a con fold, no se como será) por si a alguno le sirve.



-- TP2 Individual - Paradigma Funcional
-- Alumno: Franco Hecht
-- Legajo: 140.939-6

type Nombre = String
type Edad = Float
type Peso = Float
type Tonificacion = Float

data Persona = Socio Nombre Edad Peso Tonificacion deriving Show

ana = (Socio "ana" 25.0 50.0 6.0)
andres = (Socio "andres" 30.0 120.0 1.0)
pancho = (Socio "francisco" 40.0 120.0 1.0)

--1
saludable :: Persona -> Bool
saludable persona = not (obeso persona) && tonificacion persona > 5.0

--2
quemarCalorias :: Float -> Persona -> Persona
quemarCalorias calorias persona | obeso persona = bajarDePeso (calorias/150.0) persona
| edad persona > 30.0 && calorias > 200.0 = bajarDePeso 1 persona
| otherwise = bajarDePeso (calorias / (peso persona * edad persona)) persona

--3
caminataEnCinta :: Float -> Persona -> Persona
caminataEnCinta minutos persona = quemarCalorias (5.0 * minutos) persona

entrenamientoEnCinta :: Float -> Persona -> Persona
entrenamientoEnCinta minutos persona = quemarCalorias (velocidadPromedio minutos * minutos) persona

pesas :: Float -> Float -> Persona -> Persona
pesas minutos kilos persona | minutos > 10.0 = aumentarTonificacion (kilos / 10.0) persona
| otherwise = persona

colina :: Float -> Float -> Persona -> Persona
colina minutos inclinacion persona = quemarCalorias (2.0 * minutos * inclinacion) persona

montana :: Float -> Float -> Persona -> Persona
montana minutos inclinacion persona = ((colina (minutos/2.0) inclinacion).(colina (minutos/2.0) (inclinacion+3.0)).(aumentarTonificacion 1.0)) persona

--4a
type Rutina = (String, Float, [(Float -> Persona -> Persona)])

rutina :: Rutina
rutina = ("rutina", 200.0, [caminataEnCinta, entrenamientoEnCinta, (pesas 100.0), (colina 20.0), (montana 50.0)]) --, pesas , colina, montana llevan argumento adicional

aplicarRutina :: Rutina -> Persona -> Persona
aplicarRutina (_, _, []) persona = persona
aplicarRutina (nombreRutina, duracionRutina, (ej:ejs)) persona = aplicarRutina (nombreRutina, duracionRutina, ejs) (ej duracionRutina persona)

{-
No pude aplicar fold, ya que su tipo es Funcion -> Valor Inicial -> Lista de valores -> Resultado
Y en este ejercicio, en lugar de tener una funcion y una lista de valores,
tenemos un valor (persona) y una lista de funciones (rutina)
-}

--4b
type Resumen = (Nombre, Peso, Tonificacion)

resumenRutina :: Rutina -> Persona -> Resumen
resumenRutina rutina persona = (nombreRutina rutina, (peso persona - peso (aplicarRutina rutina persona)), (tonificacion (aplicarRutina rutina persona) - tonificacion persona))

--5
--Nota: Considero que el "resumen" de una rutina, es su nombre (debido a que es poco conveniente mostrar una lista de rutinas)
rutinasSaludables :: [Rutina] -> Persona -> [String]
rutinasSaludables rutinas persona = map nombreRutina (filter (saludable.(flip aplicarRutina) persona) rutinas)

rutinas :: [Rutina]
rutinas = [("rutina", 200.0, [caminataEnCinta, entrenamientoEnCinta,(colina 20.0), (montana 50.0)]),
("rutina2", 100.0, [caminataEnCinta, (pesas 100.0), (colina 80.0), (montana 20.0)]),
("rutina3", 300.0, [caminataEnCinta, entrenamientoEnCinta, (pesas 500.0), (colina 40.0), (montana 30.0)]),
("rutina4", 500.0, [caminataEnCinta, (pesas 100.0), (colina 20.0), (montana 50.0)]),
("rutina5", 450.0, [entrenamientoEnCinta, (pesas 100.0), (colina 50.0), (montana 500.0)]),
("rutina6", 100.0, [caminataEnCinta, entrenamientoEnCinta, (pesas 100.0), (montana 100.0)])
]


--6
{-
Usando la funcion definida en este TP (rutinasSaludables) no sería posible, ya que la funcion filter
recorre toda la lista de rutinas antes de devolver las rutinas que hacen a la persona saludable,
y al ser una lista infinita nunca la terminaria de recorrer.
Lo que se podría hacer, es agregar la funcion head, para que devuelva la primer rutina que la haga
saludable. Esto funcionaría, pero tendría el problema de que, si no hay ninguna que la haga saludable,
el programa seguiría ejecutándose indefinidamente.
Ejemplo:
Main> head (rutinasSaludables rutinas pancho)
"rutina2"
-}

--Funciones Auxiliares
nombre (Socio nombre _ _ _) = nombre
edad (Socio _ edad _ _) = edad
peso (Socio _ _ peso _) = peso
tonificacion (Socio _ _ _ tonificacion) = tonificacion

obeso persona = peso persona > 100.0

bajarDePeso cantidad (Socio nombre edad peso tonificacion) = (Socio nombre edad (peso-cantidad) tonificacion)

velocidadPromedio :: Float -> Float
velocidadPromedio minutos = (velocidadMinima + velocidadMaxima minutos) / 2.0
velocidadMinima :: Float
velocidadMinima = 6.0
velocidadMaxima :: Float -> Float
velocidadMaxima minutos = 6.0 + minutos / 5.0

aumentarTonificacion cantidad (Socio nombre edad peso tonificacion) = (Socio nombre edad peso (tonificacion+cantidad))

nombreRutina (nombreRutina, _, _) = nombreRutina
duracionRutina (_, duracionRutina, _) = duracionRutina
ejerciciosRutina (_, _, ejerciciosRutina) = ejerciciosRutina

--Pruebas

{-
Main> saludable ana
True
Main> saludable andres
False

Main> quemarCalorias 300 pancho
Socio "francisco" 40.0 118.0 1.0

Main> caminataEnCinta 40 pancho
Socio "francisco" 40.0 118.6667 1.0

Main> entrenamientoEnCinta 40 pancho
Socio "francisco" 40.0 117.3333 1.0
Main> pesas 50 15 pancho
Socio "francisco" 40.0 120.0 2.5
Main> colina 5 40 pancho
Socio "francisco" 40.0 117.3333 1.0
Main> montana 5 40 pancho
Socio "francisco" 40.0 117.2333 2.0

Main> aplicarRutina rutina pancho
Socio "francisco" 40.0 75.66667 22.0

Main> resumenRutina rutina pancho
("rutina",44.33333,21.0)

Main> rutinasSaludables rutinas ana
["rutina","rutina2","rutina3","rutina5","rutina6"]
Main> rutinasSaludables rutinas andres
["rutina2","rutina5","rutina6"]
Main> rutinasSaludables rutinas pancho
["rutina2","rutina3","rutina4","rutina5","rutina6"]
-}

No entiendo el problema que tenés... de hecho, estás aplicando parcialmente en tu resolución =P


Volviendo a (1), no me parece bien postear la resolución de un TP antes de corregirlo. Es como dejar que se copien =)
El enunciado dice "Mostrar un ejemplo de uso usando todos los ejercicios del punto anterior."
Es decir, la idea, es que acepte una lista de rutinas que incluya las funciones de los puntos anteriores...por eso, no creo que esté permitido cambiar las funciones de los ejercicios anteriores...por eso es que recurrí a aplicación parcial (luego de un buen rato tratando de entender como hacerlo =P)

(29-04-2014 16:42)Ichiluk escribió: [ -> ]Volviendo a (1), no me parece bien postear la resolución de un TP antes de corregirlo. Es como dejar que se copien =)
Ya no estamos en el secundario...dudo que alguno venga a "copiarse".
A mi no me parece mal, al contrario, puede ayudar al que busca como hacer tal punto o tal otro.
No creo que sea tan boludo como para entregar el TP tal cual lo publiqué =P


Off-topic:

Si no me equivoco, en 2012 cursamos juntos SSL con Solá a la noche, puede ser?
En el 1er cuatri? Si es así, es probable que sí. No se quien sos =P
(29-04-2014 15:37)sentey escribió: [ -> ]Gracias por las sugerencias, pero dudo que se acepte eso, ya que estoy modificando otras funciones, las cuales son parte del enunciado.
Dejo el TP terminado (me falto hacer el 4a con fold, no se como será) por si a alguno le sirve.



-- TP2 Individual - Paradigma Funcional
-- Alumno: Franco Hecht
-- Legajo: 140.939-6

type Nombre = String
type Edad = Float
type Peso = Float
type Tonificacion = Float

data Persona = Socio Nombre Edad Peso Tonificacion deriving Show

ana = (Socio "ana" 25.0 50.0 6.0)
andres = (Socio "andres" 30.0 120.0 1.0)
pancho = (Socio "francisco" 40.0 120.0 1.0)

--1
saludable :: Persona -> Bool
saludable persona = not (obeso persona) && tonificacion persona > 5.0

--2
quemarCalorias :: Float -> Persona -> Persona
quemarCalorias calorias persona | obeso persona = bajarDePeso (calorias/150.0) persona
| edad persona > 30.0 && calorias > 200.0 = bajarDePeso 1 persona
| otherwise = bajarDePeso (calorias / (peso persona * edad persona)) persona

--3
caminataEnCinta :: Float -> Persona -> Persona
caminataEnCinta minutos persona = quemarCalorias (5.0 * minutos) persona

entrenamientoEnCinta :: Float -> Persona -> Persona
entrenamientoEnCinta minutos persona = quemarCalorias (velocidadPromedio minutos * minutos) persona

pesas :: Float -> Float -> Persona -> Persona
pesas minutos kilos persona | minutos > 10.0 = aumentarTonificacion (kilos / 10.0) persona
| otherwise = persona

colina :: Float -> Float -> Persona -> Persona
colina minutos inclinacion persona = quemarCalorias (2.0 * minutos * inclinacion) persona

montana :: Float -> Float -> Persona -> Persona
montana minutos inclinacion persona = ((colina (minutos/2.0) inclinacion).(colina (minutos/2.0) (inclinacion+3.0)).(aumentarTonificacion 1.0)) persona

--4a
type Rutina = (String, Float, [(Float -> Persona -> Persona)])

rutina :: Rutina
rutina = ("rutina", 200.0, [caminataEnCinta, entrenamientoEnCinta, (pesas 100.0), (colina 20.0), (montana 50.0)]) --, pesas , colina, montana llevan argumento adicional

aplicarRutina :: Rutina -> Persona -> Persona
aplicarRutina (_, _, []) persona = persona
aplicarRutina (nombreRutina, duracionRutina, (ej:ejs)) persona = aplicarRutina (nombreRutina, duracionRutina, ejs) (ej duracionRutina persona)

{-
No pude aplicar fold, ya que su tipo es Funcion -> Valor Inicial -> Lista de valores -> Resultado
Y en este ejercicio, en lugar de tener una funcion y una lista de valores,
tenemos un valor (persona) y una lista de funciones (rutina)
-}

--4b
type Resumen = (Nombre, Peso, Tonificacion)

resumenRutina :: Rutina -> Persona -> Resumen
resumenRutina rutina persona = (nombreRutina rutina, (peso persona - peso (aplicarRutina rutina persona)), (tonificacion (aplicarRutina rutina persona) - tonificacion persona))

--5
--Nota: Considero que el "resumen" de una rutina, es su nombre (debido a que es poco conveniente mostrar una lista de rutinas)
rutinasSaludables :: [Rutina] -> Persona -> [String]
rutinasSaludables rutinas persona = map nombreRutina (filter (saludable.(flip aplicarRutina) persona) rutinas)

rutinas :: [Rutina]
rutinas = [("rutina", 200.0, [caminataEnCinta, entrenamientoEnCinta,(colina 20.0), (montana 50.0)]),
("rutina2", 100.0, [caminataEnCinta, (pesas 100.0), (colina 80.0), (montana 20.0)]),
("rutina3", 300.0, [caminataEnCinta, entrenamientoEnCinta, (pesas 500.0), (colina 40.0), (montana 30.0)]),
("rutina4", 500.0, [caminataEnCinta, (pesas 100.0), (colina 20.0), (montana 50.0)]),
("rutina5", 450.0, [entrenamientoEnCinta, (pesas 100.0), (colina 50.0), (montana 500.0)]),
("rutina6", 100.0, [caminataEnCinta, entrenamientoEnCinta, (pesas 100.0), (montana 100.0)])
]


--6
{-
Usando la funcion definida en este TP (rutinasSaludables) no sería posible, ya que la funcion filter
recorre toda la lista de rutinas antes de devolver las rutinas que hacen a la persona saludable,
y al ser una lista infinita nunca la terminaria de recorrer.
Lo que se podría hacer, es agregar la funcion head, para que devuelva la primer rutina que la haga
saludable. Esto funcionaría, pero tendría el problema de que, si no hay ninguna que la haga saludable,
el programa seguiría ejecutándose indefinidamente.
Ejemplo:
Main> head (rutinasSaludables rutinas pancho)
"rutina2"
-}

--Funciones Auxiliares
nombre (Socio nombre _ _ _) = nombre
edad (Socio _ edad _ _) = edad
peso (Socio _ _ peso _) = peso
tonificacion (Socio _ _ _ tonificacion) = tonificacion

obeso persona = peso persona > 100.0

bajarDePeso cantidad (Socio nombre edad peso tonificacion) = (Socio nombre edad (peso-cantidad) tonificacion)

velocidadPromedio :: Float -> Float
velocidadPromedio minutos = (velocidadMinima + velocidadMaxima minutos) / 2.0
velocidadMinima :: Float
velocidadMinima = 6.0
velocidadMaxima :: Float -> Float
velocidadMaxima minutos = 6.0 + minutos / 5.0

aumentarTonificacion cantidad (Socio nombre edad peso tonificacion) = (Socio nombre edad peso (tonificacion+cantidad))

nombreRutina (nombreRutina, _, _) = nombreRutina
duracionRutina (_, duracionRutina, _) = duracionRutina
ejerciciosRutina (_, _, ejerciciosRutina) = ejerciciosRutina

--Pruebas

{-
Main> saludable ana
True
Main> saludable andres
False

Main> quemarCalorias 300 pancho
Socio "francisco" 40.0 118.0 1.0

Main> caminataEnCinta 40 pancho
Socio "francisco" 40.0 118.6667 1.0

Main> entrenamientoEnCinta 40 pancho
Socio "francisco" 40.0 117.3333 1.0
Main> pesas 50 15 pancho
Socio "francisco" 40.0 120.0 2.5
Main> colina 5 40 pancho
Socio "francisco" 40.0 117.3333 1.0
Main> montana 5 40 pancho
Socio "francisco" 40.0 117.2333 2.0

Main> aplicarRutina rutina pancho
Socio "francisco" 40.0 75.66667 22.0

Main> resumenRutina rutina pancho
("rutina",44.33333,21.0)

Main> rutinasSaludables rutinas ana
["rutina","rutina2","rutina3","rutina5","rutina6"]
Main> rutinasSaludables rutinas andres
["rutina2","rutina5","rutina6"]
Main> rutinasSaludables rutinas pancho
["rutina2","rutina3","rutina4","rutina5","rutina6"]
-}



Una pregunta , no estas usando el tiempo total de la rutina a cada ejercicio ?. Por lo que interprete del enunciado habria que dividir la duracion total por el length de la lista de ejercicios. Ese es mi problema cuando lo hago no me deja dividir los minutos que son de tipo Float por el length de la lista que es de tipo entero, o quizas yo interprete mal la consigna. Si alguno me podria dar alguna idea me seria de mucha ayuda. Saludos
(29-04-2014 15:37)sentey escribió: [ -> ]Gracias por las sugerencias, pero dudo que se acepte eso, ya que estoy modificando otras funciones, las cuales son parte del enunciado.
Dejo el TP terminado (me falto hacer el 4a con fold, no se como será) por si a alguno le sirve.



-- TP2 Individual - Paradigma Funcional
-- Alumno: Franco Hecht
-- Legajo: 140.939-6

type Nombre = String
type Edad = Float
type Peso = Float
type Tonificacion = Float

data Persona = Socio Nombre Edad Peso Tonificacion deriving Show

ana = (Socio "ana" 25.0 50.0 6.0)
andres = (Socio "andres" 30.0 120.0 1.0)
pancho = (Socio "francisco" 40.0 120.0 1.0)

--1
saludable :: Persona -> Bool
saludable persona = not (obeso persona) && tonificacion persona > 5.0

--2
quemarCalorias :: Float -> Persona -> Persona
quemarCalorias calorias persona | obeso persona = bajarDePeso (calorias/150.0) persona
| edad persona > 30.0 && calorias > 200.0 = bajarDePeso 1 persona
| otherwise = bajarDePeso (calorias / (peso persona * edad persona)) persona

--3
caminataEnCinta :: Float -> Persona -> Persona
caminataEnCinta minutos persona = quemarCalorias (5.0 * minutos) persona

entrenamientoEnCinta :: Float -> Persona -> Persona
entrenamientoEnCinta minutos persona = quemarCalorias (velocidadPromedio minutos * minutos) persona

pesas :: Float -> Float -> Persona -> Persona
pesas minutos kilos persona | minutos > 10.0 = aumentarTonificacion (kilos / 10.0) persona
| otherwise = persona

colina :: Float -> Float -> Persona -> Persona
colina minutos inclinacion persona = quemarCalorias (2.0 * minutos * inclinacion) persona

montana :: Float -> Float -> Persona -> Persona
montana minutos inclinacion persona = ((colina (minutos/2.0) inclinacion).(colina (minutos/2.0) (inclinacion+3.0)).(aumentarTonificacion 1.0)) persona

--4a
type Rutina = (String, Float, [(Float -> Persona -> Persona)])

rutina :: Rutina
rutina = ("rutina", 200.0, [caminataEnCinta, entrenamientoEnCinta, (pesas 100.0), (colina 20.0), (montana 50.0)]) --, pesas , colina, montana llevan argumento adicional

aplicarRutina :: Rutina -> Persona -> Persona
aplicarRutina (_, _, []) persona = persona
aplicarRutina (nombreRutina, duracionRutina, (ej:ejs)) persona = aplicarRutina (nombreRutina, duracionRutina, ejs) (ej duracionRutina persona)

{-
No pude aplicar fold, ya que su tipo es Funcion -> Valor Inicial -> Lista de valores -> Resultado
Y en este ejercicio, en lugar de tener una funcion y una lista de valores,
tenemos un valor (persona) y una lista de funciones (rutina)
-}

--4b
type Resumen = (Nombre, Peso, Tonificacion)

resumenRutina :: Rutina -> Persona -> Resumen
resumenRutina rutina persona = (nombreRutina rutina, (peso persona - peso (aplicarRutina rutina persona)), (tonificacion (aplicarRutina rutina persona) - tonificacion persona))

--5
--Nota: Considero que el "resumen" de una rutina, es su nombre (debido a que es poco conveniente mostrar una lista de rutinas)
rutinasSaludables :: [Rutina] -> Persona -> [String]
rutinasSaludables rutinas persona = map nombreRutina (filter (saludable.(flip aplicarRutina) persona) rutinas)

rutinas :: [Rutina]
rutinas = [("rutina", 200.0, [caminataEnCinta, entrenamientoEnCinta,(colina 20.0), (montana 50.0)]),
("rutina2", 100.0, [caminataEnCinta, (pesas 100.0), (colina 80.0), (montana 20.0)]),
("rutina3", 300.0, [caminataEnCinta, entrenamientoEnCinta, (pesas 500.0), (colina 40.0), (montana 30.0)]),
("rutina4", 500.0, [caminataEnCinta, (pesas 100.0), (colina 20.0), (montana 50.0)]),
("rutina5", 450.0, [entrenamientoEnCinta, (pesas 100.0), (colina 50.0), (montana 500.0)]),
("rutina6", 100.0, [caminataEnCinta, entrenamientoEnCinta, (pesas 100.0), (montana 100.0)])
]


--6
{-
Usando la funcion definida en este TP (rutinasSaludables) no sería posible, ya que la funcion filter
recorre toda la lista de rutinas antes de devolver las rutinas que hacen a la persona saludable,
y al ser una lista infinita nunca la terminaria de recorrer.
Lo que se podría hacer, es agregar la funcion head, para que devuelva la primer rutina que la haga
saludable. Esto funcionaría, pero tendría el problema de que, si no hay ninguna que la haga saludable,
el programa seguiría ejecutándose indefinidamente.
Ejemplo:
Main> head (rutinasSaludables rutinas pancho)
"rutina2"
-}

--Funciones Auxiliares
nombre (Socio nombre _ _ _) = nombre
edad (Socio _ edad _ _) = edad
peso (Socio _ _ peso _) = peso
tonificacion (Socio _ _ _ tonificacion) = tonificacion

obeso persona = peso persona > 100.0

bajarDePeso cantidad (Socio nombre edad peso tonificacion) = (Socio nombre edad (peso-cantidad) tonificacion)

velocidadPromedio :: Float -> Float
velocidadPromedio minutos = (velocidadMinima + velocidadMaxima minutos) / 2.0
velocidadMinima :: Float
velocidadMinima = 6.0
velocidadMaxima :: Float -> Float
velocidadMaxima minutos = 6.0 + minutos / 5.0

aumentarTonificacion cantidad (Socio nombre edad peso tonificacion) = (Socio nombre edad peso (tonificacion+cantidad))

nombreRutina (nombreRutina, _, _) = nombreRutina
duracionRutina (_, duracionRutina, _) = duracionRutina
ejerciciosRutina (_, _, ejerciciosRutina) = ejerciciosRutina

--Pruebas

{-
Main> saludable ana
True
Main> saludable andres
False

Main> quemarCalorias 300 pancho
Socio "francisco" 40.0 118.0 1.0

Main> caminataEnCinta 40 pancho
Socio "francisco" 40.0 118.6667 1.0

Main> entrenamientoEnCinta 40 pancho
Socio "francisco" 40.0 117.3333 1.0
Main> pesas 50 15 pancho
Socio "francisco" 40.0 120.0 2.5
Main> colina 5 40 pancho
Socio "francisco" 40.0 117.3333 1.0
Main> montana 5 40 pancho
Socio "francisco" 40.0 117.2333 2.0

Main> aplicarRutina rutina pancho
Socio "francisco" 40.0 75.66667 22.0

Main> resumenRutina rutina pancho
("rutina",44.33333,21.0)

Main> rutinasSaludables rutinas ana
["rutina","rutina2","rutina3","rutina5","rutina6"]
Main> rutinasSaludables rutinas andres
["rutina2","rutina5","rutina6"]
Main> rutinasSaludables rutinas pancho
["rutina2","rutina3","rutina4","rutina5","rutina6"]
-}



Una pregunta , no estas usando el tiempo total de la rutina a cada ejercicio ?. Por lo que interprete del enunciado habria que dividir la duracion total por el length de la lista de ejercicios. Ese es mi problema cuando lo hago no me deja dividir los minutos que son de tipo Float por el length de la lista que es de tipo entero, o quizas yo interprete mal la consigna. Si alguno me podria dar alguna idea me seria de mucha ayuda. Saludos
Si, tenes razon matiasm , fue un error mío. Supongo que se puede usar alguna funcion para convertirlo a float, la verdad no le di demasiada importancia a esa parte...

-------------


Aprovecho para dejar otra duda que me surgió:


funciones = [(+1),(*2),(+3),(*4)]
valor = 1
--Quiero obtener el resultado de "valor" luego de aplicarle todas las funciones, es decir: ((((1)+1)*2)+3)*4 = 28
--Lo quiero hacer de 2 formas: con recursividad y con fold

aplicar [] valor = valor
aplicar (f:fs) valor = aplicar fs (f valor)


--Main> aplicar funciones valor
--28


--Hasta ahi todo bien, pero, como lo haría con fold???

Alguien pudo hacer el --4a aplicando foldl ??? wall
Tenés que usar al gimnasta como semilla, a la lista de rutinas como la lista, y la función va a ser una lambda que le aplique al segundo argumento (el elemento de la lista) la duración de cada rutina (tiempo total/tamaño de la lista) y el primer argumento (el gimnasta). Algo así como \x y -> y duracion x
[Imagen: 3342ljm.png]
Páginas: 1 2
URLs de referencia