Tabla de Contenidos

Problemario del taller de Haskell

Funciones Simples

probar con 0, 3, 5 y 9
probar con 20, 35, 40, 65, 70 y -30.
probar con (0,8,2) y con (3,3,3).
probar con (1,2,3), (-5,8,73490), (3,3,3).
probar con (0,1), (2,2), (3,1).
probar con 5 y 9, con -8 y 9, con -10 y -1, con 0 y 0 y con 0 y 3
probar con (1,2,3), (-1,-2,-3), (1,1,1), (-1,2,-3).
probar con 1523, 2000, 5000, 5001, -3000, 2001 y 1999
probar con 3, -5 y 0.
probar con -8, 3 y 0.
probar con 2, 0 y 5.
probar con 50 (30,200), 30 (30,200), -40 (200,1000), 50 (200,30), 200 (30,200), 201 (30,200).
probar con 2 y 2, 0 y 3, 3 y 0 y 5 y 3.
probar con [1,2,3], con [3,3,3] y con [].
probar con [1,2,3], con [3,3,3] y con [].
probar con [1,2,3], con [3,3,3], con [0], con [0,1] y con [].

Un poco más complicadas...

probar con 1984, 1985, 1900 y 2000.

Suponer que las fechas son correctas (no puede ser que aparezca un (32,15,1999)) y el primer argumento es menor que el segundo.

probar con (16,4,1980) y (17,5,1992), (16,4,1980) y (14,5,1992), y con (16,4,1980) y (15,4,1992).

Para usar Definiciones Locales

area.h.b.d = 2*frente + 2*lado + 2*tapa

         where
            frente = ...
            lado   = ...
            tapa = ...

donde h es su altura, b es su ancho y d su profundidad, y donde frente, lado y tapa son las áreas de las caras frontal, lateral y superior, respectivamente.

capítulo 2 del problemario de Pepe Gallardo)

raices a b c
 | disc >= 0 = ((-b+raizDisc)/denom,(-b-raizDisc)/denom)
 | otherwise = error "raices complejas"
   where
      disc     = ...
      raizDisc = ...
      denom    = ...

Divide y Conquista

Suponer el siguiente juego: m jugadores en ronda comienzan a decir los números naturales consecutivamente. Cuando toca un multiplo de 7 o un número con algún dígito igual a 7, el jugador debe decir pip en lugar del número.
Se pide: encontrar un predicado pip.n, pip : Int → Bool que dado un número 0<=n<10000 devuelva diga cuando el jugador debe decir pip.
Para hacerlo habrá que definir previamente las siguientes funciones: unidad,decena,centena,unidadDeMil : Int → Int.

Funciones Simples

probar con 0, 3, 5 y 9
probar con 20, 35, 40, 65, 70 y -30.
probar con (0,8,2) y con (3,3,3).
probar con (1,2,3), (-5,8,73490), (3,3,3).
probar con (0,1), (2,2), (3,1).
probar con 5 y 9, con -8 y 9, con -10 y -1, con 0 y 0 y con 0 y 3
probar con (1,2,3), (-1,-2,-3), (1,1,1), (-1,2,-3).
probar con 1523, 2000, 5000, 5001, -3000, 2001 y 1999
probar con 3, -5 y 0.
probar con -8, 3 y 0.
probar con 2, 0 y 5.
probar con 50 (30,200), 30 (30,200), -40 (200,1000), 50 (200,30), 200 (30,200), 201 (30,200).
probar con 2 y 2, 0 y 3, 3 y 0 y 5 y 3.
probar con [1,2,3], con [3,3,3] y con [].
probar con [1,2,3], con [3,3,3] y con [].
probar con [1,2,3], con [3,3,3], con [0], con [0,1] y con [].

Un poco más complicadas...

probar con 1984, 1985, 1900 y 2000.

Suponer que las fechas son correctas (no puede ser que aparezca un (32,15,1999)) y el primer argumento es menor que el segundo.

probar con (16,4,1980) y (17,5,1992), (16,4,1980) y (14,5,1992), y con (16,4,1980) y (15,4,1992).

Para usar Definiciones Locales

area.h.b.d = 2*frente + 2*lado + 2*tapa

         where
            frente = ...
            lado   = ...
            tapa = ...

donde h es su altura, b es su ancho y d su profundidad, y donde frente, lado y tapa son las áreas de las caras frontal, lateral y superior, respectivamente.

capítulo 2 del problemario de Pepe Gallardo)

raices a b c
 | disc >= 0 = ((-b+raizDisc)/denom,(-b-raizDisc)/denom)
 | otherwise = error "raices complejas"
   where
      disc     = ...
      raizDisc = ...
      denom    = ...

Divide y Conquista

Suponer el siguiente juego: m jugadores en ronda comienzan a decir los números naturales consecutivamente. Cuando toca un multiplo de 7 o un número con algún dígito igual a 7, el jugador debe decir pip en lugar del número.
Se pide: encontrar un predicado pip.n, pip : Int → Bool que dado un número 0<=n<10000 devuelva diga cuando el jugador debe decir pip.
Para hacerlo habrá que definir previamente las siguientes funciones: unidad,decena,centena,unidadDeMil : Int → Int.

Recursivos lineales

Aplicación

probar con [3,2,1], con [0,1,2] y con [].
probar con 1 [3,2,1], 10 [3,2,1], 0 [0,1,2] y [] 3.

Acumulación

probar con [3,2,1], con [0,1,2] y con [].
probar con [1,2,3,4], [0,1,2,3,4], [0], [3,2,1], [3,2,1,1], [3,2,1,1,1], [3,2,1,1,1,1], [-8,3,2], [].
probar con [1,2,3,4], [0,1,2,3,4], [0], [3,2,1], [3,2,1,1], [3,2,1,1,1], [3,2,1,1,1,1], [-8,3,2], [].
probar con [(1,1)], [] y [(2,1),(1,2)].
probar con [ [], [0,1,2], [] ], [ [] ], [ [1,2], [3,4] ] y ["hola","chau"].
probar con [0], [], [1], [0,0,0,0], [0,1,0,1], [1,2,3], ['a','b','c']
probar con ['A','A','A'], ['a','A'], [], ['a','b','c','d'], ['A','B','C','D'], [1,'a',2].
probar con [0,1,2], [-3,-5], [], [0,1,2,10], [30,5].
probar con [], [0,0,0,0], [1,2,3,4], [0] y [1,5,7,0,9]

Filtros

probar con [0,1,2,3,4,5], [3,5,7], [2,4,6], [2,2,3,2,4], [].
probar con [0,0,0,0], [1,1,1,1], [], [0,0,0,1], [1,0,0,0].

probar con 2 [0,1,2,3,4,5], 3 [3,5,7], 4 [2,4,6], 0 [2,2,3,2,4], 2 [].

Misceláneas

probar con 2 y 10, con 3 y 3, con 0 y 5 y con 4 y 2.
probar con [0,1,2], con [2,1,0], con [1] y con [].
probar con [0,1,2], con [2,1,0], con [1] y con [].
probar con 0 0, 0 10, 10 0, (-1) 5, 5 (-1).
probar con [1], [], [1,1,1], (desdeHasta.0.9999), (repetir.42.1)
probar con [], [1], [1,2], [1,2,3], (desdeHasta.0.9999)++[0]. 
probar con 0, 2, 170.
probar con [], [0], [0,0,0], [0,1], [0,1,0,1,0,1,0,1]

Definir la función numeroE, numeroE : Integer → Double, donde numeroE.n retorna la sumatoria 1/0! + 1/1! + 1/2! + … 1/n!. Ejemplo: numeroE.10 = 2.71828180114638.
Probar como se pueden ir obteniendo todas los dígitos, comparar con el primer millón de dígitos.

Generalizando los recursivos

Los siguientes ejercicios permiten generalizar algunas funciones que hemos visto hasta ahora, de forma que podemos escribir una sola función que, sólo cambiando un parámetro, haga lo que antes hacían muchas funciones distintas.

Aplicaciones (map)

probar con mapNumeros.(*2).[0,1,2,3], mapNumeros.absoluto.[-10,0,10].
probar con mapNumeroString.rangoPrecio.[1000,2000,3000,4000,5000,6000,7000]
probar con mapa.ordena.[(1,0)(0,1)], mapa.segundo3.[(10,20,30),(12,22,32),(14,24,34)],
  mapa.longitud.[[],[1],[1,2]], mapa.(\x -> [x,x])."tartamuda".
PREGUNTA: ¿Qué función del preámbulo de Haskell es un mapa genérico?

Filtros (filter)

probar con filtraNumeros.entre0y9.[], filtraNumeros.entre0y9.[10,20,30].
probar con filtro.esMultiplo2.[1,2,3,4,5,6], filtro.(esMultiplo.3).[1,2,3,4,5,6,7,8,9,10],
filtro.(==0).[1,2,3,4].
PREGUNTA: qué función del preámbulo de Haskell es un filtro genérico?

Acumuladores (fold)

probar con concatena.[ [],[],[] ], concatena.[ [], [True], [] ], concatena.[].
probar con paraTodoInt.multiplo2.[2,3,4], paraTodoInt.entre0y9.[1,2,4,2,1], paraTodoInt.multiplo2.[].
probar con acumulaInt.(+).0.[1,2,3], acumulaInt.(*).1.[1,2,3].
probar con acumulaBool.(||).False.(map entre0y9 [10,20,30,2,40]).
probar con todos los ejemplos de las versiones menos generales.
PREGUNTA: ¿Qué funciones del preámbulo de Haskell son los acumuladores genéricos? ¿Por qué hay 2?

Recursivos en dos argumentos

probar con [] [10], [10] [], [9,10] [9,11], (desdeHasta.10.10000) (desdeHasta.10.9999).
Pregunta: ¿Cuál es el compara genérico del preámbulo?
probar con [] [], [1] [1], [] [1,2,3], [1,2,3] [], [4] [4,5,6].
Pregunta: ¿Cuál es el cerrar2 genérico del preámbulo?
probar con 2 [0,1], 2 [0], 2 [], 0 [], 0 [0,1,2], (-1) [0,1,2].
Pregunta: ¿Cuál es el tomar genérico del preámbulo?
probar con 2 [0,1], 2 [0], 2 [], 0 [], 0 [0,1,2], (-1) [0,1,2].
Pregunta: ¿Cuál es el tirar genérico del preámbulo?
probar con 2 [0,1], 2 [0], 2 [], 0 [], 0 [0,1,2], (-1) [0,1,2].
Pregunta: ¿Cuál es el nEsimo genérico del preámbulo?
probar con [] [1,2,3], [1,2,3] [], [1,2,3] [4,5,6], [4,5,6] [1,2,3],
  [0,1,2,5] [3,4], [1,2,3] [1,2,3], [] [], [3,4] [0,1,2,5].

Para componer

Ejemplo: edadReal [ ("Ana","M",45,False), ("Pedro","H",30,False), ("Teresa","M",35,True), ("Esteban","H",40,False) ] = [ ("Ana",45), ("Pedro",30), ("Teresa",45), ("Esteban",35) ]
Ejemplo: escalaImpuesto [("Perez",30), ("Gomez",67), ("Martinez",55), ("Rodriguez",24)] = [("Gomez",201),("Rodriguez",72)]

* Definir la función cuantosCumplen, cuantosCumplen :: (Int → Bool) → [Int] → Int, que dado un predicado p y una lista de enteros xs, cuenta cuántos elementos de la lista cumplen con p.

Para lucirse