Documentos de Académico
Documentos de Profesional
Documentos de Cultura
INFORMÁTICA
GRADO DE MATEMÁTICAS
Ejercicios de examen de Haskell
Cada ejercicio se ha enmarcado en el tema más avanzado que hay que haber estudiado para
resolverlo completo. Para resolución hacen falta conocimientos de ese tema y de todos, o parte,
de los temas anteriores.
INDICE
1. Febrero 2013. Fun. Tema 2 ................................................................................................................................... 3
2. Febrero 2013. Cubo. Tema 4 (aleatorios) ....................................................................................................... 3
3. Febrero 2013. menorNatural. Temas 3 y 4 ................................................................................................... 4
4. Febrero 2013. colaPrioridad. Tema 6 ............................................................................................................... 4
5. Julio 2013. Serpientes. Tema 3 ............................................................................................................................ 4
6. Septiembre 2013. Secuencia Cíclica. Tema: 3. ............................................................................................. 5
7. Septiembre 2013. 2. INTERSECCION. Temas: 3. .......................................................................................... 5
8. Septiembre 2013. esSubExpr. Tema 5. ........................................................................................................... 5
9. Septiembre 2013. Distancia. Tema: 6 ............................................................................................................... 5
10. Febrero 2014. Es-suave y Suaves. Tema 4 ................................................................................................... 6
11. Febrero 2014. Maya, Willy y Casandra. Tema 5 aleatorios .................................................................. 6
12. Febrero 2014. Expr. Tema 5 .............................................................................................................................. 7
13. Julio 2014. PreMax. Tema 3 ................................................................................................................................ 7
14. Julio 2014. partir. Tema 3 ................................................................................................................................... 7
15. Julio 2014. Distribuye. Tema 2, 4 ..................................................................................................................... 7
16. Julio 2014. La tortuga. Tema: 5 ......................................................................................................................... 8
17. Septiembre 2014. UnosYCeros. Tema 3 ........................................................................................................ 8
18. Septiembre 2014. Supercreciente. Tema: 3 ................................................................................................ 8
19. Febrero 2015. Parte. Tema 3 ............................................................................................................................. 9
20. Febrero 2015. algDiv. Tema 4. .......................................................................................................................... 9
21. Febrero 2015. Bolas blancas y negras. Tema 4 .......................................................................................... 9
22. Febrero 2015. Cola con dos pilas. Tema 6 ................................................................................................... 9
23. Julio 2015. Particion. Tema 4. ......................................................................................................................... 10
24. Julio 2015. K-esimo. Tema 3 ........................................................................................................................... 10
25. Julio 2015. Cerillas de Banach. Tema 4 ...................................................................................................... 10
26. Julio 2015. Arbol recursivo. Tema 6 ........................................................................................................... 10
27. Septiembre 2015. Romanos. Tema 3. .......................................................................................................... 11
28. Septiembre 2015. Suaves. Tema 4 ................................................................................................................ 11
29. Septiembre 2015. Chuck a Luck. Tema 4 ................................................................................................... 11
30. Febrero 2016. Números de Luhn. Tema 2 y 3. ........................................................................................ 12
31. Febrero 2016. CalculoMul. Tema 3 .............................................................................................................. 12
32. Febrero 2016. Expresiones Sum y Prod. Tema 5 ................................................................................... 13
33. Julio 2016. Binarios 10. Tema 3 ..................................................................................................................... 14
1
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
34. Julio 2016. Lap. Temas 3 y 4 ........................................................................................................................... 15
35. Julio 2016. La red social. Tema 5 .................................................................................................................. 16
36. Septiembre 2016. Look-and-say. Tema 3 .................................................................................................. 17
37. Septiembre 2016. Matrices. Tema 2. ........................................................................................................... 18
38. Septiembre 2016. Binarios CeroUno. Temas: 5 y 3. .............................................................................. 19
39. Febrero 2017. Nicomano. Tema 3. ............................................................................................................... 21
40. Febrero 2017. Valida. Temas 6, 3 y 2 .......................................................................................................... 21
41. Febrero 2017. Fechas. Tema 5. ...................................................................................................................... 22
42. Julio 2017. Raiz Cuadrada. Tema 2,3 ........................................................................................................... 23
43. Julio2017. Collatz. Tema 3 y 4 ........................................................................................................................ 25
44. Julio2017. Cubos. Tema 3 ................................................................................................................................. 25
45. Julio 2017. Infija Prefija. Tema 6 ................................................................................................................... 25
46. Septiembre 2017. Juego de la cuerda. Tema 4 ........................................................................................ 26
47. Septiembre 2017. La ley d'Hondt. Tema 3. ............................................................................................... 27
48. Septiembre 2017. Palíndromo. Temas 3. .................................................................................................. 28
49. Febrero 2018. El número PI. Temas 4 ........................................................................................................ 28
50. Febrero 2018, Codificar. Temas 2 y 3 ......................................................................................................... 29
51. Febrero 2018. El tren. Tema 5 ....................................................................................................................... 30
52. Julio 2018. Sustituir elementos lista. Tema 3. ........................................................................................ 31
53. Julio 2018. Anagramas. Temas 3 y 4. ........................................................................................................... 31
54. Julio 2018. Hamming. Tema 6. ....................................................................................................................... 32
55. Julio 2018. Grafo bidireccional etiquetado. Temas 5 y 6 ................................................................... 32
56. Septiembre 2018. Números de kaprekar. Tema 3 ................................................................................. 33
57. Septiembre 2018. Lista Cuadrados. Temas 2 y 4 .................................................................................. 33
58. Septiembre 2018. Grafo bidireccional 1. Temas 5 y 6 ........................................................................ 34
59. Febrero 2019. Alternada. Tema 2 y 3 ....................................................................................................... 34
60. Febrero 2019. El tipo Polinomios. Tema 5 .............................................................................................. 35
61. Febrero 2019. Un juego de números. Temas 3 y 5 ............................................................................... 35
62. Julio 2019. Fracciones continuas . Tema 3, 4 y 5 ................................................................................. 36
63. Julio 2019. Ampliando las funcionalidades de las Pilas . Tema 6 ................................................. 37
64. Julio 2019. El 46 . Tema 3,4 ........................................................................................................................... 37
65. Septiembre 2019. Numeros desnudos y de Dudeney. Tema 2 y 3 ................................................. 38
66. Septiembre 2019. Multiplicacion Rusa. Tema 3 y 4 .............................................................................. 38
67. Septiembre 2019. Multiplicacion Egipcia . Tema 3 y 4 ........................................................................ 39
68. Septiembre 2019. Arboles de Calkin-Wilf. Tema 5 ............................................................................... 39
69. Febrero 2020. Una sucesión (Tema 3) ....................................................................................................... 40
70. Febrero 2020. Donde Está (Temas 2 y 3) .................................................................................................. 40
71. Febrero 2020. Polinomios (Temas 5) ......................................................................................................... 41
72. Febrero 2020. Arbol de Factorización (Tema 6) .................................................................................... 42
73. Julio 2020. Pirámide de números ................................................................................................................. 43
74. Julio 2020. Un juego con la baraja española ............................................................................................. 44
75. Septiembre 2020. Fichas de dominó ........................................................................................................... 46
2
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
1. Febrero 2013. Fun. Tema 2
Sea h una función que toma dos enteros y devuelve un entero (h :: Int -> Int -> Int) que suponemos ya definida,
y sea fun la siguiente función:
fun xs = sum [ h 5 x | x <- xs ]
a) Da una nueva definición de la función fun, llamándola fun2, de modo que calcule lo mismo que la anterior
pero que use la función map en lugar de una lista por comprensión.
a) Sea la siguiente función:
fun' :: (Integral a) => a -> Bool
fun' x = not (even (abs x))
Da una nueva definición de esta función, pero defínela usando el operador de composición de funciones.
2. Febrero 2013. Cubo. Tema 4 (aleatorios)
Consideremos un cubo con sus aristas numeradas tal como se indica en la figura. 8 7
Supongamos definida la función aleatoriosDe :: [a] -> Semilla -> [a] que
devuelve una lista infinita pseudo-aleatoria con los elementos de la lista 5 6
primerargumento. Usando semillas distintas podemos modelar distintos
experimentos. 4 3
Consideremos el siguiente experimento: Los vértices 7 y 8 del cubo están
envenenados. Una hormiga parte del vértice número 1 y se mueve 1 2
aleatoriamente por las aristas del cubo hasta que en algún momento llega a uno de los
vértices envenenados y muere. Para realizar un movimiento, la hormiga selecciona aleatoriamente (con
probabilidad uniforme) uno de los tres vértices que se encuentran conectados (mediante una arista) con el
vértice en el que se encuentra y se desplaza a dicho vértice.
Por ejemplo, el resultado de un experimento podría ser 1 → 2 → 6 → 7, que indica que la hormiga realizó 3
movimientos antes de morir (partió del vértice 1; en dicho momento podía moverse a uno de los siguientes
vértices: 2, 4 o 5; desde el 1 decidió ir al 2; a partir de aquí decidió ir al 6 y por último fue al 7, donde murió).
a) Define una función experimento que tome como parámetro una semilla y devuelva una lista con todos los
vértices por los que pasa la hormiga al simular un experimento como el descrito, usando para generar los
números aleatorios que correspondan a las decisiones tomadas por la hormiga la semilla pasada como
parámetro. La lista resultado debe incluir, además de los vértices intermedios del recorrido, el inicial (vértice
1) y el final donde muere la hormiga (vértice 7 u 8). Además, los vértices de la lista deben estar en el orden en
que fueron recorridos por la hormiga.
b) Escribe una función promedioMovimientos que realice 1000 experimentos (con semillas distintas) y
calcule el promedio del número de movimientos que realiza la hormiga antes de morir. Para ello, realiza los
1000 experimentos, determina el número de movimientos realizados en cada experimento y calcula la media
aritmética de dichos valores.
c) Escribe una función probRepe que determine la probabilidad de que la hormiga pase más de una vez por el
mismo vértice antes de morir al realizar un recorrido. Para ello, realiza 1000 experimentos y cuenta como
casos favorables aquellos en los que el camino correspondiente contenga vértices repetidos. Tu función debe
devolver como resultado el cociente entre los casos favorables y el número de experimentos realizados.
3
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
3. Febrero 2013. menorNatural. Temas 3 y 4
Define una función menorNatural que calcule el menor número natural n tal que n! (factorial de n) termina
exactamente en 1987 ceros. Para resolver este problema, puedes usar cualquier función predefinida que
consideres útil y definir otras que sean útiles (cálculo del factorial, obtener cifras de un número, etc.)
4. Febrero 2013. colaPrioridad. Tema 6
Una cola con prioridad es una cola en la que cada uno de los valores almacenados tiene asociada una prioridad
(que supondremos un valor entero). Cuando se introduce un nuevo valor en la cola, éste se sitúa delante de todos
aquellos que tienen una prioridad inferior. Si hay valores en la cola con la misma prioridad, el nuevo valor se sitúa
detrás de ellos. Es decir, el orden de los elementos en la cola viene dado por sus prioridades, y a igualdad de
prioridades, los que entraron antes están delante. Al sacar un elemento de la cola, siempre saldrá el primero según
el orden anterior, es decir, de los de mayor prioridad, aquél que entró primero.
Sea el siguiente tipo recursivo para representar colas con prioridad:
type Prioridad = Int
data ColaPrioridad a = Vacía | Nodo Prioridad a (ColaPrioridad a) deriving Show
Con el que, por ejemplo, podemos definir la siguiente cola con prioridad de cadenas de caracteres:
a) Una serpiente de palabras es una secuencia de palabras donde cada palabra comienza con la letra con la
que acaba la palabra previa. Define una función esSerpiente que tome una lista de palabras y compruebe si
es una serpiente. Por ejemplo:
esSerpiente [“hola”, “amigo”, “oscura” ] => True
esSerpiente [“hola”, “amigo”, “rojo”, “oscuro” ] => False
NOTA: tu solución no debe producir un error en ningún caso y siempre debe devolver True o False.
b) Define una función serpiente que tome una lista de palabras y devuelva una de las serpientes más
largas (con más palabras) que se puede construir usando dichas palabras. La serpiente resultado podrá
no incluir alguna de las palabras dadas pero no debe incluir palabras duplicadas. Para resolver este
ejercicio, puedes asumir que en la lista de palabras proporcionadas no hay repeticiones de palabras y que
ninguna palabra es vacía. Por ejemplo:
AYUDA: La idea es construir todas las serpientes posibles y seleccionar la más larga. Puede ser útil definir
primero una función que tome un carácter y una lista de palabras y devuelva una de las serpientes más
largas que se pueden construir con dichas palabras y tal que la primera palabra de la serpiente comience
por el carácter dado.
4
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
Así, la secuencia cíclica de la figura puede ser representada con la lista [1,3,4,7,9], pero también, por ejemplo,
con la lista [4,7,9,1,3].
Define una función mismoCiclo que tome dos listas y devuelva True si ambas representan la misma
secuencia cíclica. Por ejemplo:
mismoCiclo [1,3,4,7,9] [9,1,3,4,7] => True
mismoCiclo [1,3,4,7,9] [1,2,4,7,9] => False
Por ejemplo, la expresión "X*(13+X)" se representa con Prod X (Suma (Num 13) X).
Define la función esSubExpr que, dadas dos expresiones devuelva True si la primera es una subexpresión
de la segunda, es decir, si la primera expresión aparece dentro de la segunda. Por ejemplo:
esSubExpr (Suma (Num 13) X) (Prod X (Suma (Num 13) X)) => True
esSubExpr (Suma (Num 13) X) (Suma (Num 13) X) => True
esSubExpr (Suma X (Num 13)) (Prod X (Suma (Num 13) X)) => False
d) Define una propiedad para comprobar con QuickCheck que el resultado de la función suaves es
correcto.
El problema de las tres abejas es el siguiente: en una estancia hay inicialmente tres abejas (Maya, Willy y
Casandra) y en otra estancia contigua ninguna. Cada segundo hay una abeja de las tres (al azar con probabilidad
1/3) que cambia de estancia. En promedio, ¿cuántos segundos harán falta para que pasen todas las abejas de la
primera a la segunda estancia?
6
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
Escribe un programa en Haskell para simular el problema de las tres abejas y para estimar el promedio de
segundos necesarios para alcanzar la situación final.
Define la función máximo :: Expr -> [Integer] -> (Integer,[Integer]) tal que máximo e xs devuelva la
tupla formada por el máximo valor de la expresión e para los puntos en xs y la lista con los puntos de xs en los que
e alcanza dicho máximo. Por ejemplo:
2
ya que el máximo de la expresión (10 + ((1 – x) x)) en el intervalo [-3..3] es 100 y dicho
máximo se alcanza cuando x vale 0 o 1.
AYUDA: define primero una función que evalúe una expresión dado el valor de la variable x.
de modo que preMax xs n parte la lista xs en dos trozos. El primero contiene el mayor segmento inicial de xs tal
que la suma de sus elementos sea menor o igual que n, y el segundo contiene el resto de la lista xs. Por ejemplo
Una función partir :: [Integer] -> Integer -> [[Integer]] de modo que partir xs n parte la lista xs
en segmentos de máxima longitud cuyas sumas son menores o iguales que n. Por ejemplo:
partir [1,2,3,1,3,2,6,1] 9 => [ [1,2,3,1], [3,2], [6,1] ]
15. Julio 2014. Distribuye. Tema 2, 4
Define, usando listas por comprensión, la función distribuye que compruebe si una función distribuye sobre un
operador para todos los elementos de un conjunto. Por ejemplo, si
doble x = 2*x,
entonces
distribuye doble (+) [1..10] => True
ya que la función doble distribuye con la suma para el conjunto [1..10]:
∀x, y ∈[1..10] . doble x + doble y = doble( x + y)
La función, el operador y el conjunto se pasarán como parámetros. Indica además el tipo polimórfico de
dicha función.
7
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
16. Julio 2014. La tortuga. Tema: 5
Para describir el movimiento de una tortuga digital sobre una cuadricula, usamos el siguiente tipo:
data MovTortuga = Av | Dr | Rp Int [MovTortuga] deriving Show
De manera que:
Av significa que la tortuga avance una unidad,
Dr que gire 90 grados a la derecha, y
Rp n ms que repita n veces los movimientos que se encuentran en la lista ms.
Definimos también el tipo que registra toda una serie de movimientos
type CaminoTortuga = [MovTortuga]
Por ejemplo, un camino posible es
camino1 = [Av,Dr,Av,Dr,Dr,Dr,Rp 4 [Av,Dr,Dr,Dr],Dr]
a) Sea la longitud el número de segmentos unitarios que tiene un camino. Define una función para
determinar la longitud de un camino.
longitud :: CaminoTortuga -> Int
Por ejemplo:
longitud camino1 => 6
b) Sea el siguiente tipo para representar la orientación de la tortuga
data Orientación = N | S | E | O deriving Show
de modo que la orientación puede ser N (Norte), S (Sur), E (Este) u O (Oeste).
Define una función que tome la orientación inicial de la tortuga y un camino y devuelva la orientación final
tras seguir el camino dado.
orientación :: Orientación -> CaminoTortuga -> Orientación
Por ejemplo:
b) Define una función multUnosYCeros que devuelva una lista con los múltiplos de un número formados por cifras
que son unos y ceros. Por ejemplo:
take 4 (multUnosYCeros 3) => [111,1011,1101,1110]
c) Define una propiedad para comprobar con QuickCheck que todo número natural mayor que cero tiene al
menos un múltiplo cuyos dígitos son todos unos y ceros
8
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
19. Febrero 2015. Parte. Tema 3
Define una función recursiva parte que tome una lista de enteros y devuelva dos listas: una con los
elementos pares y otra con los impares. Para resolver este problema debes definir una única función recursiva
que genere la solución recorriendo una única vez los elementos de la lista parámetro. Por ejemplo:
parte [2,9,3,7,1,9,4] => ([2,4],[9,3,7,1,9])
define, sin usar recursividad, una función algDiv que tome dos listas de enteros y devuelva todos los
elementos de la primera que lista que son divisores de algún elemento de la segunda. Por ejemplo:
algDiv [4,5,7,3] [10,9,27,13] => [5,3]
algDiv [2,3,5] [7,11,13] => []
Tenemos dos casilleros con un número par de casillas (n) cada uno. Inicialmente, todas las casillas del primer
casillero contienen bolas blancas y las del segundo bolas negras. A continuación, se toma al azar (con
probabilidad uniforme) una bola de cada uno de los casilleros y se intercambian (la bola seleccionada del
primer casillero se coloca en la casilla de la bola seleccionada del segundo casillero y la bola seleccionada
del segundo casillero se coloca en la casilla de la bola seleccionada del primero). El proceso se repite hasta
que cada casillero contenga n/2 bolas blancas y n/2 bolas negras. Escribe una función en Haskell que tome
como parámetros el nº de bolas (n) y una semilla (s), realice una simulación con dicha semilla y devuelva el
nº de intercambios de bolas realizados para llegar a la situación final. Escribe también una función que calcule
la esperanza (nº promedio de intercambios realizados) al realizar el experimento anterior.
1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4
Situación inicial (n=4) En el primer intercambio, se cambió la bola 2 Situación final (tras varios
del casillero 1º con la bola 3 del casillero 2º intercambios)
22. Febrero 2015. Cola con dos pilas. Tema 6
La estructura de datos cola puede ser implementada de un modo eficiente usando dos pilas. Los elementos
de la cola se encuentran distribuidos en las dos pilas según se explica a continuación. Los elementos de la
primera pila se corresponden con los primeros elementos de la cola representada (el tope de esta pila es el
primero de la cola, el que se encuentra debajo del tope es el segundo de la cola, etc). Los elementos de la
segunda pila van en la cola tras los de la primera pila, pero en este caso, el orden es inverso: el tope de la
segunda pila es el último elemento de la cola, el que se encuentra bajo el tope es el penúltimo de la cola, etc.
Para introducir un elemento en la cola, solo hay que introducirlo en la segunda pila, con lo que queda situado
tras el último de la cola. Para sacar un elemento de la cola, se saca el tope de la primera pila, siempre que
dicha pila no esté vacía; si ésta estuviese vacía, habría que pasar previamente todos los elementos de la
segunda pila a la primera y luego realizar la extracción.
Escribe un módulo de biblioteca donde se defina el tipo Cola según se ha descrito, de modo que se exporte
el tipo Cola que has definido y todas las operaciones propias de esta estructura. Para resolver este problema,
puedes suponer definido e importar el módulo Pila que hemos estudiado en el tema 6.
9
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
Usando recursividad y sin usar funciones predefinidas, define una función polimórfica de orden
superior particion que tome una propiedad (o predicado) y una lista, y devuelva dos listas: una
con los elementos que cumplen la propiedad y otra con los que no la cumplen.
24. Julio 2015. K-esimo. Tema 3
Consideremos una lista cuyos elementos se encuentran desordenados. El objetivo es definir una
función sobrecargada que devuelva el k-ésimo menor elemento de la lista sin ordenar ésta
(consideraremos que el 0-ésimo menor es el elemento mínimo de la lista). Por ejemplo:
10
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
a) Una rama de un árbol es un camino que va desde el nodo raíz a una hoja. Define una función
ramas que devuelva todas las ramas de un árbol. Por ejemplo:
ramas arbol1 => [[1,2,4],[1,2,5],[1,2,6],[1,3,7]]
b) Define una función polimórfica de orden superior algunoCadaRama que tome un predicado y
un árbol, y que devuelva verdadero si en cada rama del árbol hay al menos un elemento que
verifica dicho predicado. Por ejemplo:
algunoCadaRama even arbol1 => False
algunoCadaRama odd arbol1 => True
27. Septiembre 2015. Romanos. Tema 3.
En la notación romana para expresar números, los valores de cada una de las letras utilizadas son los siguientes:
M vale 1000, D vale 500, C vale 100, L vale 50, X vale 10, V vale 5 e I vale 1.
Un número romano es una secuencia de letras. Para pasar un número romano a decimal, se recorren sus letras
desde la última a la primera (de derecha a izquierda) y se suman o restan los valores de cada una de ellas. El
valor de la última cifra siempre suma y, para las demás cifras, su valor restará si la cifra que le sigue (cifra a su
derecha) es mayor, o sumará en caso contrario.
Por ejemplo, el número romano MCMXCIX vale 1000 - 100 + 1000 – 10 + 100 - 1 + 10 = 1999.
Define una función romanoADecimal que tome una cadena de caracteres (correspondiente a un número romano)
y devuelva su valor.
28. Septiembre 2015. Suaves. Tema 4
La función zipWith se encuentra predefinida del siguiente modo:
zipWith :: (a -> b -> b) -> [a] -> [b] -> [c]
zipWith f (x:xs) (y:ys) = f x y : zipWith f xs ys
zipWith _ _ _ = []
Da una definición no recursiva de la función esSuave usando, entre otras, la función zipWith.
Define la función suaves tal que suaves n (siendo n un entero mayor que 0) devuelva todas las sucesiones
suaves de longitud n con último término 0. Por ejemplo,
suaves 2 => [[1,0],[-1,0]]
suaves 3 => [[2,1,0],[0,1,0],[0,-1,0],[-2,-1,0]]
Sea la siguiente función que devuelve una lista infinita con los resultados de tirar un dado:
import Mates.Aleatorios
dado :: Semilla -> [Dardo]
dado s = aleatoriosDe [1..6] s
Usando dicha función, podemos modelar distintos experimentos aleatorios proporcionando distintas semilla. En
una jugada del juego Chuck a Luck, un jugador tira un dado tres veces. Si obtiene un seis gana 1 euro, si obtiene
dos seises gana 2 euros y si obtiene tres seises gana 3 euros; si no obtiene ningún seis pierde un euro.
a) Supongamos que un jugador tiene siempre suficiente dinero para seguir jugando mientras lo desee. Escribe
una función que, dada una semilla, use la función dado con dicha semilla para simular 1000 jugadas del juego
Chuck a Luck (debes procesar 3000 elementos de la lista devuelta por dado, ya que cada jugada son tres tiradas)
y que devuelva una lista con 1000 enteros, correspondientes a los euros que gana o pierde (número positivo o
negativo) el jugador en cada jugada.
11
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
b) Sea el saldo correspondiente a un experimento como el anterior la cantidad que acaba ganando (positiva) o
perdiendo (negativa) el jugador tras realizar las 1000 jugadas. Escribe una función que realice 1 millón de
experimentos con distintas semillas (cada uno de 1000 jugadas) y devuelva la media de los saldos obtenidos por
el jugador en cada experimento.
Dado un número entero positivo de n cifas (por ejemplo 49927398716) para verificar si cumple el algoritmo
de Luhn.
i. Multiplicamos por 2 los dígitos que ocupan las posiciones pares empezando por el final (sombreado
en la tabla inferior):
(1×2) = 2, (8×2) = 16, (3×2) = 6, (2×2) = 4, (9×2) = 18
ii. Sumamos los dígitos que ocupaban las posiciones impares con los dígitos de los productos obtenidos:
6 + (2) + 7 + (1+6) + 9 + (6) + 7 + (4) + 9 + (1+8) + 4 = 70
iii. Si el resto de dividir el total entre 10 es igual a cero, el número es correcto.
Se pide
1) Implementar la función luhn tal que dado un número diga si cumple las restricciones de Luhn.
Utilizar listas por comprensión (1 punto)
luhn 49927398716 -> True
luhn 49927398717 -> False
2) Implementar la luhn función tal que, dado un número, diga si cumple la suma de verificación de
Luhn. Utilizar recursividad. También se pueden utilizar las funciones auxiliares del apartado anterior.
(0,5 puntos)
3) Definir la sigLuhn tal que, dado un número, si éste cumple la suma de verificación de Luhn
devuelva el dígito (o dígitos) que se podría añadir al final (a la derecha) para que el número resultante
también cumpliese el algoritmo de Lunh. Si el número no cumple la suma de verificación de Luhn se
sacará un menaje de error (0,5 puntos)
1) Definir una función expresionDe que dada una lista de listas de números devuelva la expresión
correspondiente según el tipo de datos Expr, que es la suma de los productos de cada sublista.
expresionDe [[2,2,2,5,5],[2,3,5],[5]] à
Sum [Prod [2,2,2,5,5],Prod [2,3,5],Prod [5]]
expresionDe [[4, 5, 6, 7]] à
Sum [Prod [4,5,6,7]]
2) Define la función expresionToString tal que dada un elemento del tipo expresión devuelva una
cadena de caracteres con su representación algebraica, tal y como muestran los siguientes
ejemplos.. Suponed implementada una función numToStringChar tal que dado un numero devuelve
el carácter de ese número.
numToStringString 4 à “4”
13
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
expresionToString (Sum [Prod [2,2,2,5,5],Prod [2,3,5],Prod [5]]) à
"(2 * 2 * 2 * 5 * 5) + (2 * 3 * 5) + (5)"
3) Ahora se quiere definir una funcion evaluaExpr que evalue una expresión dando como resultado el
valor numérico de hacer el sumatorio de los productos
Definir la función aBinarioL que dado un número en formato decimal convierta un número de
formato decimal a binario y como una lista de ceros y unos, en una lista.
aBinarioL 2 à[1,0]
aBinarioL 5 à[1,0,1]
aBinarioL 100 à[1,1,0,0,1,0,0]
La suma de números binarios se realiza de derecha a izquierda, es decir, de los bits de menos
peso a los de más, igual que se hace en la suma de números decimales. Cada par de dígitos se
suma entre ellos, dándose los casos de la tabla adjunta. De esta forma al sumar de derecha a
izquierda el acarreo dígito a dígito, se dan los casos de la tabla adjunta, según los valores de los
dígitos que se suman, y se generan dos valores: el dígito resultante y el correspondiente
acarreo.
Argumentos de entrada Resultado
Digito 1 Digito2 Acarreo [digito-resultante, acarreo-salida]
0 0 0 [0,0]
0 0 1 [1,0]
0 1
0 [1,0]
1 0
0 1
1 [0, 1]
1 0
1 1 0 [0, 1]
1 1 1 [1, 1]
14
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
2) Definir la función sumDigBinaria que calcule en binario la suma de dos dígitos teniendo
en cuenta el acarreo (sin convertir los números a decimal en ningún momento ni usando el
operador suma de Haskell). El primer argumento es el digito 1, el segundo el digito2 y el tercero
es el acarreo. El resultado será una lista con dos valores, el primero el resultado y el segundo el
acarreo según la tabla anterior. Utilizar guardas para implementar la función.
sumDigBinaria 1 0 0 à [1, 0]
sumDigBinaria 1 1 0 à [0, 1]
sumDigBinaria 0 0 0 à [0, 0]
sumDigBinaria 1 1 1 à [1, 1]
3) Utilizando la función sumDigBinaria,, llamada SumDigBinariaNum tal que dados dos
dígitos, devuelva el número binario resultante en una lista. (No se considerará válida si no se
usa la función sumDigBinaria):
sumDigBinariaNum 0 0 à [0]
sumDigBinariaNum 0 1 à [1]
sumDigBinariaNum 1 1 à [1,0]
4) Definir una función que utilice las funciones anteriores que sean necesarias, llamada sumaB
que tenga como entrada dos números en formato decimal, los convierta en números binarios y
luego realice la suma en binario
sumaB 1 3 à [1,0,0]
sumaB 3 1 à [1,0,0]
sumaB 4 2 à [1,1,0]
sumaB 1 0 à [1]
sumaB 7 3 à [1,0,1,0]
Importante. No se puede utilizar en ningún momento el operador suma de haskell, ni hacer la
suma de los números en formado decimal en cualquiera otra forma y convertirlos luego en
binario. SE de be implementar la función utilizando las funciones de los apartados anteriores
que se consideren necesarias
34. Julio 2016. Lap. Temas 3 y 4
1) Escribe una función llamada lap, de lista anterior posterior, que genere la siguiente lista
infinita (1,5 puntos)
[[1],[0,2], [-1, 1, 1, 3] , [-2, 0, 0, 2, 0, 2,2,4]....]
15
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
donde una lista empieza por 1 y los sucesivos elementos resultan del anterior sustituyendo
cada elemento por su antecesor y su sucesor (sumando y restando 1), es decir, el 1 por el 0
y el 2, el 0 por el -1 y el 1, el 2 por el 1 y el 3, etc. La lista empieza por el 1.
take 4 lap à [[1],[0,2],[-1,1,1,3],[-2,0,0,2,0,2,2,4]]
2) Definir la función lapRandom con un parámetro de entrada que es una semilla y que genera
una lista infinita según se indica a continuación. Con la semilla de entrada se generarán dos
números aleatorios, el primero para indicar por qué número empieza el primer elemento de la
lista, y el segundo para indicar el valor que se suma y resta para calcular el antecesor y posterior
de cada elemento, como se hacia en la función anterior. Suponed que está importada la librería
Mates.aleatorios(1 punto)
Por ejemplo, si la semilla es 5, y a partir de esa semilla se generan los números aleatorios 9 y 2,
[9] será el primer elemento, y el siguiente es 9-2 y 9+2, luego será aplicado en +2 y -2 a cada
elemento anterior para calcular el siguiente:
take 4 (lapRandom 5) à
[[9],[7,11],[5,9,9,13],[3,7,7,11,7,11,11,15]]
35. Julio 2016. La red social. Tema 5
Tenemos una red social que permite a los usuarios enviar mensajes 140 caracteres. Además
permite seguir a otros usuarios, citarlos o ser seguido. Para cada usuario se los siguientes datos
1. El identificador del usuario, que es una cadena que empieza por @. Por ejemplo “@adria”
2. Lista de mensajes creados por el usuario ordenados cronológicamente. Cada mensaje es una
cadena de caracteres con la siguiente estructura: una serie de datos numéricos,
correspondientes al año, mes, dia, hora , minuto y segundo y el texto.
3. Lista de seguidores: es una lista de identificadores de usuarios ordenados alfabéticamente
4. Lista de usuarios que esta siguiendo, como una lista de identificadores ordenados
alfabéticamente.
Asi, para el cocinero adria, tenemos los siguientes valores de ejemplo, donde tiene dos menajes,
cuatro seguidores y está siguiendo a cinco usuarios.
Nombre Nombre Valor de cada campo
variable campo
adria Persona “@adria”
Mensajes "2016 3 12 9 23 Siempre he cocinado con el objetivo de aportar algo
técnico y conceptual a la cocina y de emocionar a los clientes, como mis
amigos @berasategui @sandavoal y @luisjanez"
Para almacenar los datos de un usuario definimos los siguientes tipos de datos, done Cuenta
almádena todo lo reverente a un usuario
type Persona = String
type Mensajes = [String]
type Seguidores = [Persona]
type Siguiendo = [Persona]
data Cuenta = Usuario Persona Mensajes Seguidores Siguiendo
16
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
deriving Show
Se pide
1) Suponiendo declarado el tipo de datos Cuenta y las siguientes variables m,se, y si
m = ["2016 3 12 9 23 Siempre he cocinado con el objetivo de aportar algo técnico y conceptual a la
cocina y de emocionar a los clientes, como mis amigos @berasategui @sandavoal y @luisjanez",
4) Suponiendo que el mensaje está bien escrito según la estructura definida anteriormente, definir la
declaración y la función addMensaje que permite añadir un mensaje nuevo a un usuario, y
devuelve una cuenta nueva con el mensaje añadido (1 punto)
addMensaje adria "2016 2 1 ahora mismo estamos presentando @chicote y @oliver la nueva carta de un
restaurante de Madrid"
à
Usuario "@adria"
["2015 3 10 23 10 La cocina de @osuna es de alta calidad y creativa, sin fronteras, como la de
@berasategui",
"2016 2 1 ahora mismo estamos presentando @chicote y @oliver la nueva carta de un restaurante de
Madrid",
["@berasategui","@dacosta","@danigarica","@ramonluis"]
["@berasategui","@davidmunoz","@joseandres","@luisjanez","@sandoval"]
5) Definir la cabecera de librería RedSocial que exporte el tipo de datos Cuenta y las funciones
definidas a lo largo de este ejercicio (0,5 puntos). No hace falta definir el tipo y las funciones de
nuevo, es suficiente con poner un comentario “aquí van los tipo”, “aquí van las funciones”
36. Septiembre 2016. Look-and-say. Tema 3
La secuencia look-and-say es una secuencia recursiva de números que ha sido definida y
estudiada por John Conway. La manera de definir la secuencia es la siguiente:
- Se toma un número de entrada
- Se mira el número y visualmente se agrupan los números que tienen el mismo dígito
17
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
- Se dice el número de izquierda a derecha, grupo por grupo diciendo cuantos dígitos hay y luego el
dígito que es. Así para todos los números de la secuencia.
- Ese el número siguiente de la secuencia.
Ejemplo, si empiezo con el número 1
1 à(un 1) 1 1 à (dos uno) 2 1 à (un dos) (un uno) 1 2 1 1 à (un uno) (un dos) (dos uno) à
1 1 1 2 2 1
1) Definir la función contar que recibe como parámetro una secuencia y devuelve una lista de dos
elementos el número de veces que está éste repetido el primer elemento de la secuencia (hasta que
aparece uno distinto e independientemente de si luego aparece en el resto de la secuencia) y el elemento.
Implementar la función usando recursividad (0,8 puntos):
contar [1,1,1,2,2,1,1,1] à [3, 1] -- al principio, el 1 está 3 veces
contar [2, 1] à [1, 2] –- el 2 está una vez
contar [3,1,1,3,1,4,1,1,3,1,1,2]] à [1, 3] --al principio, el 3 esta una vez
2) Definir la funcion haskell las (de look-and-say) tal que dado un número de inicio y un número n de
términos devuelva la secuencia de n términos correspondiente. Escribir brevemente el procedimiento
seguido y luego poner la implementación (0,7 puntos)
las [1] 6 à
[[1],[1,1],[2,1],[1,2,1,1],[1,1,1,2,2,1],[3,1,2,2,1,1]]
las [2] 7 à
[[2],[1,2],[1,1,1,2],[3,1,1,2],[1,3,2,1,1,2],[1,1,1,3,1,2,2,1,1,2],
[3,1,1,3,1,1,2,2,2,1,1,2]]
3) Utilizando las funciones definidas en el apartado anterior que sean necesarias, definir en
haskell la función las’ (look-and-say’) tal que dado un número de inicio devuelva la secuencia
infinita look-and-say (0,5 puntos)
take 6 (las' [1]) à
[[1],[1,1],[2,1],[1,2,1,1],[1,1,1,2,2,1],[3,1,2,2,1,1]]
Se pide implementar con listas por comprensión y/o funciones de orden superior (sin usar
recursividad) las siguientes funciones:
1) Tres funciones tal que dada una matriz devuelva la fila, columna o elemento de la posición
indicada (0,6 puntos: 0,2 cada una), utilizando listas por comprensión: filaM, columnaM, elementoM
productoM [[3, 2, 1], [1, 1, 3], [0, 2, 1]] [[2, 1], [1, 0], [3, 2]]
à [[11,5],[12,7],[5,2]]
38. Septiembre 2016. Binarios CeroUno. Temas: 5 y 3.
Se ha definido el tipo de datos Binario que trabaja únicamente con ceros y con unos :
data Binario = Cero | Uno deriving (Show, Eq)
En general, un número binario representa con ceros y unos una cantidad numérica. Así el 1001
es el número 9
Uno Cero Cero Uno Numero binario
3 2 1 0 posicion
2 2
3 2 2
1 2 2 posicion
0
19
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
Para pasar un número en formato decimal a binario, se divide el número del sistema decimal
entre 2, cuyo resultado entero se vuelve a dividir entre 2, y así sucesivamente hasta que el
dividendo sea menor que el divisor, 2. Es decir, cuando el número a dividir sea 1 finaliza la
división. A continuación se ordenan los restos empezando desde el último al primero,
simplemente se colocan en orden inverso a como aparecen en la división. Este será el número
binario que buscamos.
Así, el número 9 en binario se representa como 1001 y con el tipo de datos Binario sería
[Uno, Cero, Cero, Uno]
1) (1,5 puntos) Definir la función aBinarioL que dado un número en formato decimal convierta un número
de formato decimal a binario y como una lista de ceros y unos, en una lista del tipo de datos Binario.
aBinarioL 6 à [Uno,Uno,Cero]
aBinarioL 3 à [Uno,Uno]
2) (1 punto) Definir la función aDecimal dada una lista que representa un numero codificado en binario y
representado con el tipo de datos Binario, lo convierta de formato Binario a un número decimal
utilizando listas por comprensión
aDecimal [Uno, Cero, Cero, Uno] à 9
aDecimal [Uno, Uno, Cero] à 6
La suma de números binarios se realiza de derecha a izquierda, es decir, de los bits de menos
peso a los de más, igual que se hace en la suma de números decimales. Cada par de dígitos se
suma entre ellos, dándose los casos de la tabla adjunta. De esta forma al sumar de derecha a
izquierda el acarreo dígito a dígito, se dan los casos de la tabla adjunta, según los valores de los
dígitos que se suman, y se generan dos valores: el dígito resultante y el correspondiente
acarreo.
Argumentos de entrada Resultado
Digito Uno Digito2 Acarreo [digito-resultante, acarreo-salida]
Cero Cero Cero [Cero,Cero]
Cero Cero Uno [Uno,Cero]
Cero Uno
Cero [Uno,Cero]
Uno Cero
Cero Uno
Uno [Cero, Uno]
Uno Cero
Uno Uno Cero [Cero, Uno]
Uno Uno Uno [Uno, Uno]
3) (1 punto) Definir la función SumaB tal que dados dos números en formato decimal los convierta en tipo
de datos Binario, calcule la suma binaria de ambos y devuelva el resultado en una lista de datos de tipo
Binario, de derecha a izquierda teniendo en cuenta la suma de digito explicada en al tabla.
sumaB 2 1 à [Uno,Uno]
sumaB 10 2 à [Uno,Uno,Cero,Cero]
No son válidas soluciones que no conviertan los números a binario antes de hacer la suma, que
utilicen la suma de haskell o que no realicen la suma de forma binaria según se indica.
20
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
39. Febrero 2017. Nicomano. Tema 3.
1) Construir la función impares y la función nicomano. La función impares devuelve una lista infinita de números
impares. La función nicomano llamará a la función impares y devolverá el cubo de un numero n utilizando la
propiedad de Nicómaco. Implementar la función usando recursividad ( 1 punto)
take 7 impares à (1, 3, 5, 7, 9, 11, 13, 15)
nicomano 4 à 64
nicomano 3 à 27
nicomano 8 à 512
2) Sin utilizar las funciones anteriores, sino por el método aquí indicado, construir la función cubos que devuelta
una lista infinita de los números naturales al cubo. Para ello se seguirá el siguiente algoritmo:
2.1 Implementar la función empaqueta tal que dada una lista de elementos, devuelva una lista con estos elementos
empaquetados del siguiente modo: el primero, los dos siguientes, los tres siguientes.... hasta al final. Teniendo en
cuenta que la última lista puede estar truncada (es decir, puede que no tenga n+1 elementos q que la lista anterior)
(0,5 puntos)
empaqueta [1..10] à [[1],[2,3], [4, 5, 6], [7, 8, 9, 10]]
empaqueta "matematicas" à["m","at","ema","tica","s"]
empaqueta [1..11] à [[1],[2,3], [4, 5, 6], [7, 8, 9, 10] [11]]
empaqueta (take 6 impares) à [[1], [3,5], [7, 9,11]]
2.2. Implementar la función cubos (que no tiene ningún parámetro) que utilice la función empaqueta, y devuelva
una lista infinita de los cubos de los enteros positivos. Implementar esta función utilizando funciones de orden
superior (1 punto)
take 5 cubos = [1, 8, 27, 64, 125]
take 10 cubos = [1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]
40. Febrero 2017. Valida. Temas 6, 3 y 2
Se va a programar un sistema de envío y recepción de mensajes, que son cadenas de caracteres. En esos mensajes es
importante poder identificar aquellos submensajes dentro de un mensaje que pueden ser caracteres o números,
dependiendo del caso a resolver. Para ello, se implementará un programa que recibe los mensajes, mira si son
correctos, los procesa y actúa en consecuencia.
21
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
1) En una primera versión, los separadores son “(“ para indicar el inicio y “)” para indicar el final. Implementar en
haskell una función tal que dada una cadena de caracteres nos diga si el mensaje es correcto o no. No se pueden
utilizar pilas ni otra estructura de datos, sólo los tipos predefinidos de haskell (números y/o listas).
valida “(2*5+(5-3)*8+(3))” à True
valida “( 2 – (4*6)))” à False
valida “ ())(” à False
a. Implementar la función, llamándola valida1, con recursividad con acumuladores (0,4 puntos)
b. Implementar la función, llamándola valida2, con listas por comprensión (0,4 puntos)
2) En una segunda versión del programa, es necesario separar diferentes grupos de datos, que además son cambiantes
(dependen del caso a resolver), y para ello se decide que los separadores de inicio y de fin se pasan como parámetro de la
función, concretamente como pares donde le primero indica el inicio y el segundo indica el fin. Por ejemplo,
Se pide utilizar el TAD de Pilas Implementar una función llamada valida3 - que utilice como soporte el tipo abstracto de
datos Pila-, tal que reciba un mensaje (que es una cadena de caracteres) y una lista de pares, devuelva como salida True
si está bien formada, y False en caso contario (1,2 puntos)
ejemplo1 = "la casa [grande] esta lejos /distancia >40% y [100 m] de altura "
ejemplo2 = " (4 -2 [6*40]^{65})*{4-(3*5)} "
ejemplo3 = " (4 -2 [6*40]^ {65)} *{4-(3*5)} "
Para saber si un año es bisiesto, se proporciona en el fichero problema3.hs la función esBisiesto que devuelve True si un
año es bisiesto y False en caso contrario.
1) Definir el tipo Fecha que permita crear las fechas según se indican, utilizar clave para su definición el carácter F y la
función fechaValida tal que dada una fecha indique si es válida, es decir, si cumple todas las restricciones indicadas (1
punto)
2) Definir la función hastaFinAnio, tal que dado un dada una fecha devuelva los días que faltan para llegar a fin de año, si
la fecha no es válida dará un error. El dia que se da como parámetro no se cuenta. (1 punto)
22
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
hastaFinAnio (F 1 1 2010) à 364 -- el dia 1 de enero no se cuenta
hastaFinAnio (F 1 1 2012) à 365 -- 2012 es bisiesto, y el dia 1 no se cuenta
hastaFinAnio (F 4 5 1988) à 241
hastaFinAnio (F 4 5 1989) à 241
hastaFinAnio (F 4 15 1988) à Exception: fecha no valida
3) Definir la función entreFechas, tal que dadas dos fechas devuelva los días que hay entre ellas. Se debe tener en cuenta
que (1 punto):
- No se cuenta el día primero, sino a partir de él. Así entre el 1 de enero de 2010 y el 1 de enero de 2011
hay 365 días (porque no contamos el 1 de enero de 2010)
- No se puede utilizar recursividad para implementar esta función. Utilizar listas por comprensión y/o
funciones de orden superior, así como las funciones definidas en los apartados anteriores.
entreFechas (F 1 1 2010) (F 2 1 2011) à 366
entreFechas (F 1 1 2010) (F 1 1 2011) à 365
entreFechas (F 1 1 2011) (F 1 1 2010) à 365 -- igual anterior, distinto orden
entreFechas (F 1 1 2011) (F 2 1 2010) à 364
entreFechas (F 1 2 1988) (F 1 3 1988) à 29 --1988 es bisiesto
entreFechas (F 1 2 1990) (F 1 3 1990) à 28 -– 1990 no es bisiesto
entreFechas (F 1 2 1990) (F 4 3 2015) à 9162
4) Implementar una función fechasNum que reciba una lista de fechas correctas y devuelva aquellas fechas cuya suma de
sus cifras (F 1 2 2010 = 1 + 2+2010 = 2013 -> 2 + 0 +1+3 = 6) sea igual que un parámetro dado. Utilizar para su
implementación funciones de plegado foldr o foldl. (0,5 puntos)
23
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
3) Implementar una función quickcheck que permita demostrar la corrección de la función raizCuadrada
del apartado anterior (0,3 puntos)
CALCULO DE LA RAIZ CUADRADA.
1. Agrupamos por parejas empezando a contar desde las unidades
las
2. unidades. Por ejemplo para 125, salen dos parejas 1-25
2.Calculamos la raíz entera de la primera pareja
4. Bajamos la siguiente pareja y la unimos al valor
calculado en el caso anterior
5. Multiplicamos por 2 el valor que tenemos en la
parte derecha, y lo apuntamos aparte
7. Subimos el 5 a la parte superior derecha, lo unimos
al numero existente a la derecha.
8. Restamos el producto obtenido de la expresión del
apartado 6m al valor que teníamos a la izquierda, y
nos da 14.
9. Repetimos el proceso con la siguente pareja, y
asi sucesivamente hasta que hayamos usado
todas las parejas.
10. Como resultado se devuelve el valor de la
parte derecha, que es la raiz cuadrada, y el
calculo restante de la parte izquierda, que es el
resto
24
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
43. Julio2017. Collatz. Tema 3 y 4
1) La secuencia de Collatz de un número entero se construye de la siguiente forma:
• si el número es par, se lo divide por dos;
• si es impar, se le multiplica tres y se le suma uno;
• la sucesión termina al llegar a uno.
1.1 Definir una función llamada collatz, tal que dado un número entero devuelva la secuencia
correspondiente, utilizando recursividad normal
collatz 20 à [20,10,5,16,8,4,2,1]
collatz 13 à [13,40,20,10,5,16,8,4,2,1]
1.2 Definir la función cuantosCollatsN que tiene como parámetro de entrada un numero positvo n, y
devuelve cuántas secuencias de collatz entre 1 y 100 tienen una longitud mayor que n.
Implementar la función utilizando alguna función de orden superior (y sin usar recursividad).
cuantosCollatsN 15 à 66
cuantosCollatsN 100 à15
Entre todos los enteros mayores a 1 hay solamente cuatro que pueden ser representados por la suma de
los cubos de sus dígitos.
n = S xi3 donde x es cualquier numero entre 1 y 500, el numero de xi’s es variable, y son todos los x
son diferentes
2) Tenemos una expresión definida en notación infija con operadores binarios definida como un string y la
queremos convertir a una lista notación prefija y postfija. Para ello se pide definir la función aPrefija y
aPostfija, que conviertan de una notación a la otra respectivamente y devuelvan el resultado como una
lista de strings
25
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
aPrefija "2+13-125*4" ["+","2","-","13","*","125","4"]
aPostfija "2 + 13-125 * 4" ["2","13","125","4","*","-", "+"]
3) Definir la función evaluaPos que evalúen una expresión definidas en notación postfija. Para la
implementación de dichas funciones se debe utilizar la estructura de datos (Pila, Cola, Grafo o Arbol) que
considere más conveniente. Justifique la elección de la estructura de datos con un comentario justo antes
de la definición dela función.
evaluaPos (aPostfija "2+13-125*4") à -485
evaluaPos (aPostfija "3-235*12") à -2818
4) (0,5 p) Definir el tipo de datos ExpresionPre que permita definir expresiones recursivas de sumas,
restas, productos, divisiones anidadas entre paréntesis en notación Prefija). La suma se indicara como
Suma, la resta como Resta, el producto como Prod, y los números enteros con Num. Los paréntesis no
son parte de la definición del tipo, sino que los gestiona el propio lenguaje. Asi, la expresión 5 + (3 * 4)
en el tipo ExpresionPre se escribiría como
e:: ExpresionPre
e = Suma (Num 5)(Prod (Num 3) (Num 4))
46. Septiembre 2017. Juego de la cuerda. Tema 4
El juego de “tirar de la cuerda” es un juego de niños en los que un grupo tira en un sentido y otro en sentido contrario. Gana el
grupo que consigue que el pañuelo rebase la línea señalada en el suelo.
Vamos a simular este juego con dos jugadores, el de la derecha, y otro el de la izquierda. La posición inicial del pañuelo es el 0, y
el movimiento a la izquierda se simula restando un valor a la posición del pañuelo y a la derecha sumando un valor a la posición
del pañuelo. El valor que se suma o se resta se decide con un dado que genera aleatoriamente números entre 1 y 6. El juego se
termina cuando el pañuelo alcanza un valor mayor o igual que 10, o menor o igual que -10.
Nombramos al jugador de la derecha como Derecha y al de la izquierda como Izquierda. Para ello definimos el tipo Jugador:
data Jugador = Izquierda | Derecha deriving (Eq, Show)
1) Implementar la función jugar que tiene como entrada el jugador que hace la primera tirada, y la semilla que se usará para
generar los números aleatorios, y devuelva como salida una tupla de dos elementos, el jugador que gana y el número de
jugadas que necesitó para conseguirlo (2 puntos)
26
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
El tipo de la función jugar, donde Semilla es el tipo definido en el paquete Aleatorios, es el siguiente
Ejemplos
jugar Izquierda 1 à (Derecha,16) -- gana el jugador de la derecha después de 16 jugadas
jugar Izquierda 2 à (Izquierda,13) -- gana el jugador de la izquierda después de 13 jugadas
jugar Izquierda 3 à (Derecha,36) -- gana el jugador de la derecha después de 36 jugadas
jugar Derecha 3 à (Izquierda,36) -- gana el jugador de la izquierda después de 36 jugadas
2) Implementar la función todasJugadas que tiene como entrada el jugador que hace la primera tirada, y la semilla que se usará
para generar los números aleatorios, y devuelva como salida la lista de valores del “pañuelo” hasta llegar al valor final (>=10 o
<=(-10)) (1 punto)
todasJugadas Derecha 3 à
[3,0,1,-1,0,-1,3,-2,0,-2,2,-3,3,-2,2,-3,-2,-6,-1,-3,-1,-2,0,-6,-1,-3,3,-3,0,-6,-3,-9, -8,-9,-6,-10]
todasJugadas Izquierda 1 à
[-4,1,-1,3,0,5,2,7,2,7,5,7,5,9,8,13]
i) Se dividen los votos obtenidos por cada candidatura entre 1, 2, 3… hasta completar el número de escaños a repartir, que en este
caso hemos fijado en 5. De este modo, tenemos la siguiente matriz bidimensional con una fila por cada partido (sombreado en esta
tabla)
ii) Elegiremos de la tabla los 5 cocientes más altos (casillas en rojo en las columnas de cálculos intermedios), de forma que al
partido A corresponderán tres escaños, al partido B un escaño y al C otro escaño respectivamente. El partido D quedará sin ningún
escaño.
Nota de implementación: Utilizar el tipo Int en lugar del tipo Integer, en este problema
1) Implementar la función fvaloresMasAltos tal que dada una matriz de números enteros todos diferentes y un numero
n, devuelva los n números más altos de esa matriz. (0,5 puntos)
matriz à [[23,21,12,15,24],[14,45,21,34,10],[46,36,124,12,10],[12,33,68,29,1]]
fvaloresMasAltos matriz 5 à[124,68,46,45,36]
fvaloresMasAltos matriz 7 à [124,68,46,45,36,34,33]
2) Implementar la función buscaPosicion que recibe como entrada un elemento y una matriz, y devuelve la posición (x, y)
que ocupa ese elemento en la matriz. Se puede suponer que todos los elementos de la matriz son diferentes. Si no encuentra
el elemento, la función devolverá [0,0]. Implementar la función con recursividad(1punto)
matriz à [[23,21,12,15,24],[14,45,21,34,10],[46,36,124,12,10],[12,33,68,29,1]]
buscaPosicion matriz 23 à (1,1)
buscaPosicion matriz 45 à (2,2)
buscaPosicion matriz 68 à (4,3)
buscaPosicion matriz 99 à (0,0) – no está en la matriz
27
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
3) Implementar la función matrizDhont que recibe la lista de partidos y votos y el de puestos a repartir, y devuelve una
lista de lista de enteros que se corresponde con la tabla de votos repartidos (la tabla gris del ejemplo). Resolver esta
función aplicando listas por comprensión (0,5 puntos)
matrizDhont [("A",258020),("B",168030),("C",114040),("D",60050)] 5 à
[[258020,129010,86007,64505,51604], [168030,84015,56010,42008,33606],
[114040,57020,38013,28510,22808],[60050,30025,20017,15012,12010]]
4)Utilizando las funciones anteriores y las que considere necesarias, implemente la función reparto que dados los
resultados de una votación y el número de puestos a repartir, devuelva la asignación de escaños, según el algoritmo
anterior. Así para el ejemplo descrito, devolvería (1 punto)
reparto [("A",258020),("B",168030),("C",114040),("D",60050)]5
à[("A",3),("B",1),("C",1),("D",0)]
Partiendo de cualquier número expresado en base 10, se puede obtener un palíndromo con el siguiente algoritmo
- Dado un número, lo sumamos a su reverso.
- Si esta suma es un palíndromo, entonces paramos;
y si no, repetimos el proceso con el número obtenido de dicha suma, hasta dar con un palíndromo.
Ejemplo:
Ejemplo de salida:
aPalindromo 59 à [59,154,605,1111]
49. Febrero 2018. El número PI. Temas 4
El número pi puede calcularse de muchas maneras. En este problema vamos a resolverlo con series infinitas, según las
propuestas de dos matemáticos famosos.
1) Según la fórmula de Gregory-Leibniz, sumando los términos formados al tomar cuatro, luego restar cuatro y dividir
entre tres, luego sumar y dividir entre 5..... Mientras más sumandos se añaden, más se acercará el resultado al valor de pi
Se pide:
1.1. Implementar la función spiLeibnizt que devuelva la lista infinita con los términos de esta serie. Usar funciones de
orden superior
take 10 spiLeibnitz à
[4.0,-1.3333333333333333,0.8,-0.5714285714285714,0.4444444444444444,-
0.36363636363636365,0.3076923076923077,-0.26666666666666666,0.23529411764705882,-0.21052631578947367]
1.2 Implementar la función piLeibnizt que devuelva el número pi correspondiente calculado con n términos de la serie.
piLeibnitz 100 à 3.1315929035585537
piLeibnitz 1000 à 3.140592653839794
28
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
2) (1,5 puntos) Por su parte Euler demostró es la multiplicación de la serie de todos los valores p2/(p2-1) siendo p un
número primo (2, 3, 5, 7, 11...) Expresado numéricamente equivale a:
2.1. (0,5 p)Implementar la función primos que devuelva una lista infinita de números primos. Utilizar recursividad
take 10 primos à [2,3,5,7,11,13,17,19,23,29]
Nota de implementación. Al hacer la división si da error, colocar delante de divisor y/o dividendo la función fromIntegral: fromIntegral a /
fromIntegral b
2.2 Implementar una función spiEuler que devuelva una lista infinita de cada uno de los productos de la formula de Euler,
es decir los valores p2/(p2-1), siendo p un número primo. Utilizar en la definición de la función alguna lista por
comprensión
take 10 spiEuler à
[1.3333333333333333,1.125,1.0416666666666667,1.0208333333333333,1.0083333333333333,1.005952380952381,1.003
4722222222223,1.0027777777777778,1.0018939393939394,1.0011904761904762]
2.2. Implementar la función piEuler que dado un número n devuelva un valor para el número pi resultante con n
elementos de la serie la lista devuelta por la función del apartado anterior, y las operaciones necesarias, según la fórmula
de Euler.
piEuler 100 à 3.1411926604946983
piEuler 1000 à 3.141572703000528
Tenemos un mensaje escrito como una cadena de caracteres que se va a compartir en una red social. El mensaje se quiere encriptar
antes de su envío, y para leerlo, el receptor lo desencriptará y para ello tendrá en su equipo el código necesario para ello.
El algoritmo de encriptado es el siguiente. La entrada son dos valores:
• mensaje m: un string que contiene un mensaje no vacío, sin espacios al principio y al final y con las palabras
separadas únicamente por un espacio
• numero n: número positivo, menor que la longitud del mensaje menos uno
ALGORITMO
m = “mas vale poco que nada”
n= 4
1. Separar el mensaje en su lista de sus palabras:
[“mas”, “vale”,”poco”,”que”, “nada”]
2. Contar las letras de cada palabra:
[3, 4, 4, 3, 4]
3. Unir todas las palabras:
”masvalepocoquenada”
4. Se reagrupan las letras según el tamaño indicado con el parámetro n. Por ejemplo, si vale 4:
[”masv”, “alep”, “ocoq”, “uena”, “da”]
5. Le damos la vuelta a cada palabra
[”vsam”, “pela”, “qoco”,”aneu”, “ad”]
6. Unir todas la palabras
[”vsampelaqocoaneuad”]
7. Se reagrupan tal como indica la inversa de la lista del paso 2, es decir, [4, 3, 4, 4, 3]
[”vsam”,”pel”, “aqoc”, “oane”, “uad”]
8. Se crea una frase con los espacios. Ese es el mensaje codificado: "vsam pel aqoc oane uad"
29
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
Se pide
1) Implementar la función formatear que recibe como entrada un string y lo devuelve formateado para que sea válido
para su codificación. Implementar esta función con recursividad con acumuladores:
• Le quita los espacios del principio y del final , si los hubiere
• Quita los espacios entre palabras que sean mayores que un espacio
formatear " era una noche muy fria " à "era una noche muy fria"
formatear "mas vale tarde que nunca " à "mas vale tarde que nunca"
formatear " " à ""
formatear " x f" à "x f"
formatear "En esos casos, se dice no. " à "En esos casos, se dice no."
2) Función codificar que recibe como entrada un mensaje, lo formatea con la función anterior y luego aplica el
algoritmo descrito. Como resultado devuelve un nuevo mensaje codificado.
codificar "mas vale poco que nada" 4 à "vsam pel aqoc oane uad"
codificar "mas vale poco que nada" 5 à "avsa mco peln euqo ada"
codificar "esto es un ejemplo" 10 à "jenuseo ts eo lpme"
codificar " " 4 " à *** Exception: el mensjae está vacio *
codificar "la casa es verde" 120 " ..> *** Exception: n debe ser menor que la longitud del
mensaje formateado menos uno
Un tren está compuesto de una locomotora principal y un número arbitrario de locomotoras auxiliares y de vagones de
pasajeros y mercancías.
• Cada locomotora (principal o auxiliar) tiene potencia para arrastrar cierta cantidad de kilogramos.
• La potencia de arrastre total de un tren es la suma de las potencias de las locomotoras que lo componen.
• Cada vagón de mercancías lleva una carga en kilogramos. Cada vagón de pasajeros está ocupado por cierto
número de pasajeros (asumiremos que cada pasajero pesa 100 Kg.).
chuchu :: Tren
chuchu = Pasajeros 28 (Pasajeros 17 (Mercancias 800 (Mercancias 1200 (Auxiliar 2500 (Principal 4000)))))
tracatra :: Tren
tracatra = Pasajeros 28 (Mercancias 800 (Pasajeros 17 (Auxiliar 2000 (Mercancias 1200 (Principal 4000)))))
pesoPasajero :: Int
pesoPasajero = 100
Nota. La definicion de tipo y las variables Tren ya están tecleadas en el fichero prob3.hs en el fichero que había que descargar del campus.
1) Definir una función puedeArrastrar que dado un tren devuelve 'True' si puede arrastrar los vagones de pasajeros y
mercancías enganchados y 'False' en caso contrario.
puedeArrastrar chuchu à True
puedeArrastrar tracatra à False
30
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
2) Definir una función asegurarArrastre que dado un tren añada, solo si es necesario, una locomotora auxiliar con la
potencia mínima para asegurar que se puede arrastrar toda la carga. La locomotora auxiliar debe quedar enganchada a la
principal.
asegurarArrastre chuchu
à Pasajeros 28 (Pasajeros 17 (Mercancias 800 (Mercancias 1200 (Auxiliar 2500 (Principal 4000)))))
asegurarArrastre tracatra
à Pasajeros 28 (Mercancias 800 (Pasajeros 17 (Auxiliar 2000 (Mercancias 1200 (Auxiliar 500 (Principal
4000))))))
2) Definir una función unirAuxiliares que dado un tren reemplace todas las locomotoras auxiliares por una única con la
suma de las potencias de las auxiliares reemplazadas.
i. La única locomotora auxiliar debe aparecer enganchada a la locomotora principal, y su nueva potencia
será la que tenía mas la suma de todas las axiliares del tren.
ii. Puede darse la situación de que debido a la unión de las auxiliares la suma de éstas sea mayor que la
principal, situación que no debería darse. En ese caso, la potencia de la auxiliar se intercambia con la
de la principal (véase el último ejemplo)
unirAuxiliares chuchu
à Pasajeros 28 (Pasajeros 17 (Mercancias 800 (Mercancias 1200 (Auxiliar 2500 (Principal 4000)))))
unirAuxiliares tracatra
à Pasajeros 28 (Mercancias 800 (Pasajeros 17 (Mercancias 1200 (Auxiliar 2000 (Principal 4000)))))
31
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
sonAnagramas “sordo” “dorso” à True
sonAnagramas “sordo” “cardo” à False
sonAnagramas “camelia” “micaela” àTrue
3.2 Implementar la función hamming, que no tiene parámetros, que devuelva una lista infinita de números de la serie
de haming según el algoritmo descrito en este enunciado. Para ello utilizar la librería Colas.hs
take 15 hamming à [1,2,3,4,5,6,8,9,10,12,15,16,18,20,24]
grafo2:: Grafo
grafo2 = [ (1, 2, 10.0), (1, 3, 50.0),
(1, 5, 20.0), (3, 4, 60.0), (3, 6, 6.0),
(4, 6, 15.0), (5, 3, 2.0)]
1) Implementar la función sucesores tal que dado un nodo devuelva sus sucesores ordenados de menor a mayor peso.
Implementar con listas por comprensión.
2) Implementar la función caminoProf, que utilice la función sucesores definida en el apartado anterior, y que tiene tres
parámetros, el grafo, un nodo inicial y un nodo final. La función devuelve el primer camino resultante de hacer una búsqueda en
profundidad. Suponed, que todos los nodos del grafos son alcanzables desde el nodo inicio, es decir, siempre hay un camino
posible.
32
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
caminoProf grafo2 6 2 à [6,3,5,1,2]
3) Dado un camino, implementar una función costeCamino que devuelva el coste de ese camino, es decir, el coste para ir desde
el nodo inicial al nodo final.
camino1 == [1,5,3,6]
costeCamino camino1 grafo2 à 28.0
56. Septiembre 2018. Números de kaprekar. Tema 3
Un número de Kaprekar es un número entero no negativo tal que los dígitos de su cuadrado se pueden separar en dos
números que sumados dan el número original.
El número 297 es un número de Kaprecar:
- El cuadrado del número 297 es 88209
- Si comprobamos todas las posibles separaciones en dos números y su correspondiente suma vemos que una
de ellas coincide con el original:
8 + 8209 = 8217 es diferente de 297
88 + 209 = 297 = 297 à Es número de Kaprekar
882 + 09 = 891 es diferente de 297
8820 + 9 = 8829 es diferente de 297
El número 345 no es número de Kaprekar:
- El cuadrado es 119025
- Comprobamos las sumas de las posibles separaciones y vemos que ninguan coincide don el original
1 + 19025 = 19026 diferente de 345
11 + 9025 = 9036 diferente de 345
119 + 025 = 144 diferente de 345
1190 + 25 = 1215 diferente de 345
11902 + 5 = 11907 diferente de 345 à No es número de Kaprekar
Queremos definir la la función esKaprekar que devuelva True si el número es de Kaprekar y False en caso contrario
esKaprekar 297 à True
esKapreKar 345 à False
33
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
58. Septiembre 2018. Grafo bidireccional 1. Temas 5 y 6
Se tiene un grafo bidireccional etiquetado con un peso entre cada par de nodos, que indica el
coste para ir de un nodo a otro. Un arco entre dos nodos quiere decir que se puede ir de uno
a otro en ambos sentidos. Por ejemplo, el grafo de la figura se representa en Haskell:
grafo2:: Grafo
grafo2 = [ (1, 2, 10.0), (1, 3, 50.0),
(1, 5, 20.0), (3, 4, 60.0), (3, 6, 6.0),
(4, 6, 15.0), (5, 3, 2.0)]
También se ha definido el tipo recursivo Arbol
data Arbol a = Vacio | N a [Arbol a] deriving Show
1) Implementar la función arbolDe tal que dado un grafo g y un nodo n construya el árbol resultante todas las ramas
posibles con todos los nodos que se pueden alcanzar desde el nodo y en el grafo g. Así, para el grafo del ejemplo y el nodo
1 se puede construir el árbol de la figura (1,5 puntos)
arbolDe grafo2 1 à
N 1
[N 2 [],
N 5 [N 3 [N 6 [N 4 []], N 4 [N 6 []]]],
N 3 [N 5 [],N 6 [N 4 []],N 4 [N 6 []]]
]
2) Suponiendo que tenemos la variable arbol2 con el resultado de la función anterior
Implementar la función costeRamas que dado un grafo y un nodo de ese grafo, construya el árbol que se puede generar
a partir de ese nodo de entrada utilizando la función anterior, y a partir de ese árbol calcule la de todas sus ramas, y el
coste de cada rama. Definir las funciones auxiliares que considere necesarias (1,5 puntos)
costeRamasArbol grafo2 1
à[([1,2],10.0),
([1,5,3,6,4],43.0),([1,5,3,4,6],97.0),
([1,3,5],52.0),([1,3,6,4],71.0),([1,3,4,6],125.0)]
Así por ejemplo, el polinomio x2 + 2x +3 se escribiría en este tipo como polinomio1= P [1, 2, 3] y 4x3
+ 2x2 + 5 se escribiría como polinomio2 = P [4, 2, 0, 5].
Se pide:
1) Definir las funciones sumaP y restaP que dados dos polinomios devuelva su suma y su resta respectivamente
(0,5 puntos)
sumaP (P [3, 2, 1, 0, 6]) (P [1, 3, 2,1]) à P [3,3,4,2,7]
sumaP (P [1, 0, 6]) (P [1,1, 1, 1, 1, 1])à P [1,1,1,2,1,7]
sumaP (P [1, 0, 6]) (P []) à P [1,0,6]
restaP (P [3, 2, 1, 0, 6]) (P [1,1])à P [3,2,1,-1,5]
2) Definir la función productoP que dados dos polinomios devuelva el producto de los dos polinomios (1 punto)
productoP (P [5,0,0,0]) (P [4, 3, 7]) à P [20,15,35,0,0,0]
productoP (P[2,1]) (P[4,3]) à P[8,10, 3]
productoP (P[2,1]) (P[4,3,2,1]) à P[8, 10, 7, 4, 1]
3) Definir la funcion derivaP tal que dado un polinomio devuelva su primera derivada (0,5 puntos)
derivaP (P[2, 1, 3, 2]) à P [6,2,3]
derivaP (P [2, 1, 0]) à P [4,1]
derivaP (P [2, 1, 0, 4, 1])à P [8,3,0,4]
derivaP (P [4, 1]) à P [4]
derivaP (P [2]) à P [0]
61. Febrero 2019. Un juego de números. Temas 3 y 5
Luis y Juan juegan a un juego muy sencillo que los tiene muy entretenidos:
1) Al inicio de una partida, ambos eligen varios números positivos menores que 100, por ejemplo tres números,
Luis: 4 7 12 Juan : 3 7 8
2) Deciden con una moneda, quien es el primero en jugar. Por ejemplo, el primero es Luis.
3) Después los ponen todos seguidos, 4712378, primero los de Luis y después los de Juan.
4) Ahora juegan por turnos, y tal y como se decidió en el paso 2, empieza Luis. En cada turno, se va sumando 1 a los
números y se ponen todos seguidos. Si ahora se genera un dígito más, el jugador que ha sumado en ese turno gana un
punto. En el ejemplo:
4.1 Luis suma 1 a cada número de forma que el 4 se convierte en 5, el 7 en 8, el 12 en 13, etc. Al ponerlos de
nuevo todos juntos queda: 5813489. Si el número del paso 3 tiene un dígito más este número, se anota un punto
para Luis, sino no se hace nada. Como el número de dígitos es siete en ambos casos, no se hace nada.
4.2. Ahora le toca a Juan que suma 1 a cada numero (por separado), luego los junta el siguiente turno le toca al
siguiente, que vuelve a sumar uno a cada número, se junta y ahora sale 69145910. Ahora 69145910 tiene un
dígito mas que 5813489, entonces se anota un punto para Juan.
Se repite el paso 4 un número de veces, por ejemplo 10. Este sería el resultado
35
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
En este caso el resultado final es 2 puntos para Juan, y 2 puntos para Luis. Es decir, Empate.
1) Implementar la función partidaResumida que recibe como entrada dos listas de n números, una por cada jugador, el
número de veces que se juega, y el número del jugador que empieza (1 para el primero, 2 para el segundo) . Como resultado
devuelven la lista de números que se van generando (considerando sólo los que hacen cambiar el número de cifras, y
alguno de los jugadores puntúa: son los que están marcados en negrita en el ejemplo anterior, donde 1 es Luis y 2 es Juan)
y el numero del jugador que ha puntuado. (1,5 puntos)
1) Implementar la función fcontinua_de que recibe como entrada una fracción ordinaria como dos números enteros
donde el primero es el numerador y el segundo es el denominador. La función devuelve como salida la fracción
continua correspondiente como una lista (1p). Utilizar recursividad
36
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
fcontinua_de 1000 24 à [41,1,2]
fcontinua_de 245 100 à [2,2,4,2]
2) Utilizando plegado y desplegado definir la función valor_fcontinuaFold que reciba como entrada una función
continua como una lista y devuelva como resultado el número real resultante de evaluarla. (1,5 p)
NOTA DE IMPLEMENTACIÓN. Se puede hacer antes, si es de utilidad (no se contabilizará en la nota), una función como fcontinua_de pero
implementada con acumuladores, y luego hacer el plegado.
3) Definir el tipo de datos FraccionOrdinaria que permita representar una fracción ordinaria.
Definir un tipo de datos FraccionContinua recursivo que permita representar una fracción continua (no es un tipo
lista, como en los apartados anteriores, es un tipo recursivo). Definir una variable de cada tipo, utilizando alguno de los
ejemplos de este apartado (0,5 puntos)
4) Definir la función deContinuaOrdinaria que recibe como entrada una variable de tipo FraccionContinua y devuelve
como resultado una variable del tipo fraccionOrdinaria equivalente. Para comprobar la solución, se puede definir el
predicado esEquivalente (la definición de esta función no se puntúa), que dadas dos fracciones ordinarias nos diga si
son equivalentes o no (1,5 p).
Una solución posible es que si la entrada es la función continua del ejemplo devuelva la fracción ordinaria 256/69
que es equivalente a 1280/345. Tanto en la entrada como en la salida se debe utilizar la representación y el tipo
elegida por el estudiante cuando definió los tipos, en el apartado anterior.
63. Julio 2019. Ampliando las funcionalidades de las Pilas . Tema 6
Se quiere ampliar el modulo Pilas.hs con las siguientes funciones.
1) lengthPila: función que recibe como entrada una pila y devuelve el número de elementos de la pila
lengthPila pila1 à 15
2) nubPila: función que quita todos los repetidos de una pila de números enteros. Como los números no tienen que estar
ordenados, la función se queda con el primer numero que aparece en la pila (más arriba).
nubPila pila1 à {1 > 2 > 3 > 4 > 5 > 34 > 6 > 9}
3) filterPila: función de orden superior que recibe con entrada una pila y un predicado, y devuelve como resultado a
los elementos que verifican el predicado , en el mismo orden
filterPila (>5) pila1 à {34 > 6 > 9}
filterPila (odd) pila1 à {1 > 3 > 3 > 5 > 5 > 9 > 5 > 5}
4) alternandoF1F2Pila: función de orden superior que tiene como parámetros una pila y dos funciones f1 y f2, y aplica
alternadamente f1 a un elemento y f2 al siguiente y apila el resultado en la misma pila
alternandoF1F2Pila (*10) (*100) pila1 à
{10 > 200 > 30 > 300 > 40 > 500 > 340 > 500 > 60 > 900 > 20 > 500 > 50 > 200 > 20}
37
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
take 10 despues46 à
[46,4624,46248,4624832,46248326,4624832612,46248326122,462483261224,4624832612248,46248326122
4832]
3.2. Utilizando funciones de orden superior implementar la función numTam que tiene como parámetro un numero
n entero mayor que tres y devuelve como resultado el primer número de la secuencia cuya longitud es al menos
n. (0,5 puntos)
numTam10 à 4624832612
numTam 20 à 46248326122483261224
numTam 3 à Error: el numero debe ser mayor que 3
numTam 4 à 4624
Utilizando listas por comprensión, implementar la función dudeney que genere los números de Dudeney (0,5 puntos)
take 4 dudeney à [1, 512, 4913, 5832]
2) Un número desnudo es aquel cuyos dígitos son todos divisores del número. Un ejemplo es el número 424, que es
divisible entre 2 y 4, es capicúa, y todo sus números no son iguales. Otro ejemplo de número desnudo es el número 212.
Define la función desnudos que no tiene parámetros y devuelva una lista con todos los números desnudos de 3 dígitos
que sean capicúas y que no tengan todas las cifras iguales. Utiliza todas las funciones auxiliares que consideres necesarias.
(0,5 puntos)
Aqui no se pone ejemplo de la ejecución porque la solución es única
1.1. Implementar la función multiplicaR, que multiplique dos números enteros mediante el algoritmo de la
multiplicación rusa. No se podrá utilizar el *en toda la implementación, sino el algoritmo descrito. Definir una
propiedad quick_check multiplicaR_p para la función multiplicaR (las dos funciones, funcionando
correctamente 1 punto) para números enteros positivos.
multiplicaR 27 82 à 2214
multiplicaR 234 124 à 29016
multiplicaR 23 15à 345
quickCheck multiplicaR_p à
+++ OK, passed 100 tests.
38
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
67. Septiembre 2019. Multiplicacion Egipcia . Tema 3 y 4
a) Empezando por 1, hago una lista donde cada elemento es dos veces el anterior y así sucesivamente hasta
llegar a un número que sea mayor que b (ese número ya no se añade) (columna 1: Se para aquí porque el 16
porque el 32 ya es mayor que 21)
b) Empezando por el número A, voy haciendo una lista donde cada elemento es dos veces el anterior. Tendrá
tantos elementos como la lista anterior (columna 2)
c) De la lista del apartado 1, selecciono aquellos números que sumados dan el número B (columna 3)
d) Sumo los elementos de la columna 2, que ocupan la misma posición que los seleccionados en el apartado
anterior y que han sido seleccionados en el paso 3.
Ejemplo 23 X 21 à 483
2.1. Implementar la función calcularLista que recibe como entrada una lista de números enteros y una cantidad n, y
devuelve como resultado la lista de números no repetidos que sumados dan el valor n, o la lista vacia si no es posible. (1
punto)
calcularLista [1, 2, 4, 8, 16] 34 à [] --no es posible
calcularLista [1, 2, 4, 8, 16] 21 à [1,4,16]
2.2 Implementar la función multiplicaE, que multiplique dos números enteros mediante el algoritmo de la multiplicación
egipcia. No se podrá utilizar el *en toda la implementación, sino el algoritmo descrito. Definir una propiedad
quick_check multiplica_e para la función multiplicaE. (las dos funciones funcionando correctamente, 1,5
puntos)
multiplicaE 23 21 à 483
multiplicaE 21 23 à 483
multiplicaE 23 15 à 345
68. Septiembre 2019. Arboles de Calkin-Wilf. Tema 5
Un árbol de Calkin-Wilf son arboles binarios done su nodo raíz es una fracción a/b, la rama izquierda es la
fracción a/a+b y la rama derecha es la facción a+b/b. Así un árbol cuya raíz es 1/1 sería el de la figura.
Se ha definido el tipo Fraccion para representar un nodo
data Fraccion a b = F a b deriving Show
1) Definir la función sucesores que tiene como entrada una fracción y como salida una lista de dos nodos, el
primero una rama izquierda del árbol de CalkinWilf, y la segundo la rama derecha.
sucesores (F 1 1) à [F 1 2, F 2 1]
sucesores (F 3 4) à [F 3 7,F 7 4]
2) Definir una nivelCW que recibe como entrada un nodo y un numero n mayor que 0 y nos devuelve de
todos los nodos de un árbol de CalkinWilf en el nivel n (contando que el nodo dado está en el nivel 1).
nivelCW (F 1 1) 2 à [F 1 3,F 3 2,F 2 3,F 3 1]
nivelCW (F 1 1) 3 à [F 1 4,F 4 3,F 3 5,F 5 2,F 2 5,F 5 3,F 3 4,F 4 1]
39
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
3) Utilizando el tipo Arbol de la librería Arbol.hs y las funciones de la librería que considere necesarios,
definir la función cocanstruirCW que dado un nodo, y un número n que indica la profundidad del árbol, devuelva
el árbol de Calkin-Wilf correspondiente.
construirCW (F 1 1) 2 à
Nodo (F 1 1) [Nodo (F 1 2) [],
Nodo (F 2 1) []]
construirCW (F 1 1) 3 à
Nodo (F 1 1) [Nodo (F 1 2)
[Nodo (F 1 3) [],
Nodo (F 3 2) []],
Nodo (F 2 1)
[Nodo (F 2 3) [],
Nodo (F 3 1) []]]
Se tiene una sucesión que se aplica a un parámetro n. El primer elemento es n. Cada elemento sucesivo se calcula como
la suma del término anterior y el producto de los dígitos no nulos del anterior.
Ejemplo: si un término es 102, el siguiente término es, 102+ (2*1) = 102 + 2 = 104
Sucesiones generadas para sucesivos valores de n
n=1 à 1, 2, 4, 8, 16, 22, 26, 38, 62, 74, 102, 104, 108, 116, 122
n=2 à 2, 4, 8, 16, 22, 26, 38, 62, 74, 102, 104, 108, 116, 122, 126, …
n=3 à 3, 6, 12, 14, 18, 26, 38, 62, 74, 102, 104, 108, 116, 122, 126, …
n=4 à 4, 8, 16, 22, 26, 38, 62, 74, 102, 104, 108, 116, 122, 126,..
Como puede verse en las sucesiones anteriores, a partir de un número (que no es el mismo en todos los casos)
una sucesión converge a la del 1, en cualquier posición de la sucesión y en cualquier número. Así, la sucesión
con n=2 converge a partir del número 2, y la sucesión con n=3 converge a partir del número 26.
Se pide
1. Definir una función sucesion que para un número n devuelva la sucesión infinita correspondiente. Usar
recursividad (0,5 p)
2. Definir la función converge que dada un valor n>1 devuelva trtes valores, el término a partir del cual
converge con la sucesión del 1, y la posición que tiene el término en la sucesión n. Usar recursividad con
acumuladores (1p)
40
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
Vamos a trabajar con polinomios cuyos coeficientes son números enteros. El polinomio [1] lo representamos
con un sinónimo de tipo
type Polinomio = [Integer]
Ejemplos
Polinomio ExpresionP
[1, 0,1, 2, 0] (((((((N 1 :* X) :+ N 0) :* X) :+ N 1) :* X) :+ N 2) :* X) :+ N 0 No está simplificada
(((((N 1 :* X ):* X) :+ N 1) :* X) :+ N 2) :* X Está simplificada
Cuando el polinomio se representa como una lista, los ceros son necesarios porque indican el grado de cada
coeficiente. Como puede observarse, los ceros aparecen en la expresión, pero realmente no son necesarios,
Así, el polinomio derivado de la lista [1, 0,1, 2, 0] es igualmente válido con o sin ceros. Lo ideal sería que los
términos con cero no aparecieran en la expresión. El binomio nulo se representa como N 0
1) Definir el predicado estaSimplificada que dado un polinomio del tipo ExpresionP devuelva True si
está
simplificada, y False en caso contrario (0,5 p)
estaSimplificada ((((((((N 1 :* X) :+ N 0) :* X) :+ N 1) :* X) :+ N 2) :* X) :+ N 0) à False
estaSimplificada ((((((N 1 :* X) :* X) :+ N 1) :* X) :+ N 2) :* X) à True
2) Definir la función simplificarP que tiene como entrada un polinomio del tipo ExpresionP y devuelva
la misma expresión pero simplificada, es decir, sin términos con valor 0 , excepto si es el polinomio
nulo que devolvería N 0 (0,5 p)
3)Definir la función aPolinomioExp tal que dada como entrada una lista, devuelva como resultado la
ExpresiónP equivalente simplificada. Resolver este apartado con plegado y desplegado y sin recursividad. No
se considerarán válidas las soluciones en las que el plegado hace un trabajo auxiliar.. Si se necesita, se puede
usar la función simplificarP definida en el apartado anterior. (1 p)
4)Utilizando recursividad, implementar la función evaluarE tal que dado un polinomio en forma de
ExpresionP, lo evalúe con el valor de x dado como parámetro. (0,5 p)
evaluarE:: ExpresionP -> Integer -> Integer
evaluarE (N 5 :* X) 10 à 50 -– 5x para 10, vale 50
evaluarE (aPolinomioExp [1,2,0,0]) 2 à16 -- x^3 + 2x^2 para 2 vale 16
evaluarE ((((((N 4 :* X) :+ N 2) :* X) :+ N 1) :* X) :+ N 1) 3 à 130
--4*x^3 + 2*x^2 * x + 1 para x = 3 vale
130
evaluarE (N 0) 100 à 0
41
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
1) Los divisores medios de un número son el divisor medio menor y el divisor medio mayor de un numero se obtienen
con el siguiente algoritmo:
• Se obtienen todos los divisores de un número n y se ordenan de menor a mayor
• Si el número de divisores es par, se extraen los dos del centro, el menor de ellos el es divisor medio menor, el
mayor de ellos es el divisor medio mayor.
• Si el número de divisores es impar. Hay dos casos:
- Si son tres divisores, el divisor medio mayor y menor, es el numero que ocupa la posición central
- Si tiene más de tres divisores, el divisor medio mayor y menor es respectivamente el que está a derecha
e izquierda de la posición central
Ejemplos:
n Divisores divisor medio menor divisor medio mayor
60 [1,2,3,4,5,6,10,12,15,20,30,60] 6 10
64 [1,2,4,8,16,32,64] 4 16
4 [1,2,4] 2 2
Implementar la función divisoresMedios que dado un número n devuelva un par con sus divisores medios, primero
el menor y segundo el mayor. (0,5p).
divisoresMedios 60 à (6,10) divisoresMedios 64 à (4,16) divisoresMedios 4 à
(2,2)
2)Los árboles de factorizacion son una representación eficiente de descomposición de un número en factores, que
cumplen las siguientes condiciones:
• El 1 nunca está en un árbol
• Los nodos que son números primos no se factorizan, y por lo tanto son hojas (nodos finales) del árbol final
• Si el nodo no es primo se factoriza generando un subarbol según el algoritmo descrito abajo. El producto
de sus sucesores inmediatos el valor del nodo padre.
• El producto de todas las hojas de cada subárbol de un nodo raíz, da como resultado el número del nodo
raíz.
ALGORITMO para construir un árbol de factorización de un número n
1.El nodo n es la raíz del árbol
2. Calcular todos los divisores del numero n.
2.1 Si el numero es un número primo, el algoritmo termina.
2.2 Si no es primo, calcular su divisor medio menor y su divisor medio mayor.
3. La rama izquierda es el árbol de factorización de divisor medio menor
4. La rama derecha es el árbol de factorización de divisor medio mayor
Se ha definido el tipo ArbolBinario para representar un árbol de factorización
data Arbol a = Hoja a
| Nodo a (Arbol a) (Arbol a)
deriving Show
2.1. Implementar la función arbolFactorizacion que tiene como entrada un numero n y devuelva como salida el
árbol de factorización correspondiente, (1 p)
arbolFactorizacion 60 à Nodo 60 (Nodo 6 (Hoja 2) (Hoja 3)) (Nodo 10 (Hoja 2) (Hoja 5))
arbolFactorizacion 15 à Nodo 15 (Hoja 3) (Hoja 5)
arbolFactorizacion 7 à Hoja 7
arbolFactorizacion 8 à Nodo 8 (Hoja 2) (Nodo 4 (Hoja 2) (Hoja 2))
arbolFactorizacion 1à *** Exception: el 1 no tiene árbol de factorizacion
2.2. Definir la propiedad esArbolFactorizacion tal que dado un árbol, devuelva True si es un árbol de factorización
y False en caso contrario. Un árbol dado es de factorización si cumple las condiciones descritas al inicio del apartado
2 (0,5p)
esArbolFactorizacion (Nodo 15 (Hoja 2) (Hoja 5)) à False. -– 2*5 no da 15
esArbolFactorizacion (Nodo 15 (Hoja 3) (Hoja 5)) à True. –- 3 y 5 son primos y 3*5==15
esArbolFactorizacion (Nodo 8 (Nodo 4 (Hoja 2) (Hoja 2)) (Hoja 2)) à True
42
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
esArbolFactorizacion (Nodo 15 (Nodo 10 (Hoja 2) (Hoja 5)) (Hoja 3)) à False, 10 *3 no da 15
2.3 Los arboles de factorización se pueden usar encontrar los primos de un número. Se pide implementar la función
factores cuya entrada es un número, internamente construye un árbol de factorización, y a partir de éste obtenga la
lista de factores primos en que puede descomponerse, ordenados de menor a mayor. Comprobar la corrección de la
función con el predicado factores_p que se probará con quickCheck. (1p)
factores 15 à [3,5]
factores 18 à [2,3,3]
factores 64 à [2,2,2,2,2,2]
factores 60 à [2,2,3,5]
ejemplo
tamaño 2 3 4 5
Una pirámide está completa cuando todas sus casillas tienen números, y todos los que están en
casillas superiores a la base, cumplen la condición de que cada casilla es la suma de los dos
inferiores. Cuando no está completa, en lugar de números hay huecos. A partir de unos números
más unos huecos, se resuelve una pirámide teniendo en cuenta la regla de que la casilla inferior
es la suma de las dos inferiores.
Una pirámide números puede representarse como una lista, donde el primer elemento es la
cima, los dos siguientes el piso inferior, y así sucesivamente. Así, una pirámide con huecos la
representamos en Haskell con la lista de la izquierda, y , su pirámide completa como la lista de
la casilla de la derecha; ambos en la tabla inferior:
[Num 22, Hueco, Hueco, Num 8, [Num 22, Num 11,
Num 3, Hueco] Num 11, Num 8, Num 3, Num 8]
Pirámide con huecos Piramide completa: sin huecos, todos los números son correctos
Para resolver el problema, definir previamente las estructuras de datos y tipos que se consideren
necesarios. Deben ponerse al principio del fichero.
1) (2 puntos) Definir la función esPiramideCompleta tal que dada una lista nos diga si es una
pirámide completa, con números que cumplen las condiciones indicadas
43
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
esPiramideCompleta [Num 22, Hueco, Hueco, Num 8, Num 3, Hueco] à False -- tiene huecos
esPiramideCompleta [Num 22, Num 11, Num 8, Num 3, Num 8] à False -- no es piramide, sobran o faltan nums
esPiramideCompleta [Num 22, Num 11, Num 11, Num 8, Num 3, Num 8] à True
esPiramideCompleta [Num 22, Num 11, Num 15, Num 8, Num 3, Num 8] à False ---11 + 15 es diferente de 22
2) (2 puntos) Definir la función resolverPiramide que devuelva todas las posibles soluciones de
una pirámide con huecos de un número n de pisos. En nuestra solución tendremos en cuenta que en la
pirámide de entrada nos van a dar al menos tantos valores como pisos puedan hacerse con los
datos que nos dan. Es decir, si la pirámide es de 3 pisos, habrá al menos tres valores en la lista de
entrada; si es de 4 pisos, al menos cuatro, etc. Aún así, pueden darse casos de pirámides que no tengan
solución (véanse los ejemplos).
La solución de este problema requiere implementar varias funciones auxiliares. Entre ellas al menos una deberá haber, una recursiva, una con
funciones de orden superior y una con listas por comprensión. Es importante que se explique el algoritmo seguido para implementar
resolverPiramide. Para cada función, su entrada, salida y qué hace cada función. SI NO SE PUEDE SEGUIR LA IMPLEMENTACIÓN CON LOS
COMENTARIOS, no se corregirá el problema.
resolverPiramide [Num 22, Hueco, Hueco, Num 8, Num 3, Hueco]à [Num 22,Num 11,Num 11, Num 8,Num
3,Num 8]
resolverPiramide [Hueco, Hueco, Hueco, Hueco, Num 11, Num 33, Num 1, Num 4, Num 9, Num 24]
à [Num 60,Num 16,Num 44,Num 5,Num 11,Num 33,Num 1,Num 4,Num 9,Num 24]
resolverPiramide [Num 22, Num 11, Num 11, Hueco, Hueco, Hueco]
à [Num 22,Num 11,Num 11,Hueco,Hueco,Hueco]
No tiene solución, aunque solo tiene 3 huecos (pensad el motivo). La función devuelve hasta donde
puede resolver
74. Julio 2020. Un juego con la baraja española
Este es un juego para la baraja española, en la que hay 4 palos (oros, bastos, espadas y copas),
cada uno de los cuales tiene 12 cartas, del 1 al 12. Vamos a contar las normas para dos
jugadores:
1) Al principio se reparten todas las cartas entre todos los
jugadores, la mitad para cada uno
2) A partir de ahí comienza el juego, donde le primero en
tirar es el jugador que no ha repartido, que echa la
primera carta que le dieron en el reparto sobre la mesa.
3) Por turnos, cada jugador echa otra carta en la que
coincida o bien el palo o bien el número con la carta que
el anterior jugador puso en la mesa.
4) Si un jugador no tiene ninguna carta para poner en la
mesa, directamente, no hace nada y cede su turno al otro
jugador.
5) El juego tiene dos formas de finalizar:
a. Si ningún jugador puede poner, porque no
tienen ninguna carta que coincida con el palo ni con el número. En ese caso se devuelve
Empate
44
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
b. Cuando un jugador se queda sin cartas; en este caso, será el ganador del juego. Se devuelve
Gana 1 si el que se queda sin cartas es el segundo jugador, o Gana 2, en el otro caso.
Los jugadores pueden tener al menos tres estrategias, que seguirán durante toda la partida:
eMismoPalo. Asistir al palo: mientras tenga cartas del palo que está en la mesa, echa del
palo. Si no tiene del palo, entonces pone del mismo número, si tiene.
eMismoNumero. Asistir al numero: mientras tenga cartas con el número que está en la
mesa, echa carta con ese número. Si no tiene con el mismo número, entonces pone del
mismo palo, si tiene.
eAzar. Al azar: Se se elige al azar entre palo y número, y luego de éntrelas elegidas, se
selecciona una carta.
1) (3,0 puntos) Implementar la función jugar2 que simule una partida de un juego de dos jugadores con
todos los elementos que sean necesarios y las funciones (con la sintaxis, entrada, salida y estructura
que se consideren necesarios):
i. Representación de los elementos del juego: las cartas y el grupo de cartas que recibe cada
jugador.
ii. Implementar la función repartir que haga el reparto de las cartas a los dos jugadores
utilizando la librería Aleatorios
iii. Implementar el juego, en la función jugar2. La semilla s será el primer parámetro y se utiliza
tanto para el reparto de cartas como para seleccionar las cartas en las estrategias.
iv. Implementar las tres estrategias descritas, que se pasarán como parámetro cuando se realice
el juego, las estrategias utilizarán la librería Aleatorios para seleccionar entre varias cartas
posibles en una jugada, para ello cada estrategia tendrá, aparte de los parámetros que se
consideren necesarios, uno para la semilla de para generar los números aleatorios.
Aunque no funcione completamente jugar2, se valorarán por separado las funciones
implementadas para simular el juego. Los nombres de los tipos de datos y de las funciones se
dejan a elección del alumno. Explicar con comentarios que hace cada función
jugar2 3 "luis" eMismoNumero "ana" eMismoPalo à Empate
jugar2 3 "luis" eMismoPalo "ana" eMismoNumero à Gana1 -- gana luis
jugar2 8 "luis" eMismoPalo "ana" eMismoNumero à Gana1 -– gana luis
jugar2 8 "luis" eMismoPalo "ana" eMismoPalo à Gana2 -- gana ana
jugar2 8 "ana" eMismoPalo "luis" eAzar à Gana1 -- gana ana
2) (1,0 puntos) Implementar la función simula que recibe como parámetro una semilla, el nombre de dos
jugadores, y la estrategia que sigue cada uno de ellos y el número de pruebas que se van a realizar. La
función devolverá dos pares: el primero con la estrategia y la probabilidad mayor de ganar, y la
segunda con su correspondiente probabilidad. La función tiene que funcionar llamando a la función
jugar anterior.
simula "ana" eMismoNumero "antonio" eMismoPalo 10 à [("ana",0.0),("antonio",0.2),("empate",0.8)]
simula "ana" eMismoNumero "antonio" eMismoPalo 100 à
[("ana",0.0),("antonio",0.11),("empate",0.89)]
simula "antonio" eMismoPalo "ana" eAzar 100 à
[("antonio",0.3),("ana",0.7),("empate",0.0)]
Vamos a realizar un experimento que nos permita saber cual de las tres estrategias es la mejor
para este juego, teniendo en cuenta que siempre reparte jugador1 y empieza jugador 1. Para ello,
se pide realizar una simulación de n jugadas con la misma semilla en las siguientes situaciones
Jugadas Jugador1 Jugador2
100 eMismoNumero eMismoPalo
100 eMismo Palo eAzar
45
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
100 eAzar eMismoNumero
Utilizando la función simula, implementar la función experimento que haga los cálculos
pertinentes para decir cual de las tres estrategias es la más ventajosa para cualquier jugador.
Para ello devolverá como resultado una lista con las estrategias ordenadas según se han
llamado en el experimento.
experimento eMismoNumero eMismoPalo eAzar 100 à [3.5e-2,0.40499999999999997,0.745]
Nos dice que jugar al azar tiene más probabilidades de ganar, y que jugar al mismo
número es el que tiene menos probabilidades de ganar
75. Septiembre 2020. Fichas de dominó
El dominó es un juego de mesa en el que se emplean unas fichas rectangulares. Una de sus caras
está dividida por dos cuadrados, cada uno de los cuales está numerado normalmente mediante
disposiciones de puntos como los dados (Wikipedia).
La numeración habitual es de cero a seis puntos, lo que compone un total de 28 piezas de dominó
siendo la ficha más grande la del seis doble. También hay dominós de 0 a 9 puntos y de 0 a 12 puntos.
En este problema vamos a llamarlo domino tamaño n, siendo las piezas de 0 a n.
En el dominó, las fichas se colocan de forma que una ficha coincide con al menos un extremo de las
que están en el tablero. Como resultado se construyen caminos de fichas, como el que se muestra en
la figura.
Fuente: http://oledomino.com/EL%20DOMINO/Eljuego.htm
Tenemos definido el tipo Ficha que nos permite representar una ficha del dominó con un par de
números enteros. Se considera que es lo mismo la ficha D 0 3 que la ficha D 3 0 (ya que así se
consideran en el juego, las fichas se giran para unirse por un lado o por otro)
Se pide
46
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
1) (1 punto ) Implementar la funcion grafoDomino, que tenga como entrada un tamaño de
dominó, y de vuelva el grafo correspondiente, teniendo en cuenta las fichas que están
relacionas con una ficha (D x y), son aquellos coinciden o bien en la x o en la y o en ambos.
Para construir la solución de la función pedida, elige una representación para el Grafo, y explicala
brevemente en el fichero de la solución. Puede ser alguna de las utilizadas en los problemas de
clase o de prácticas.
3) (1punto) Dada una ficha y un dominó de tamaño n, implementar la funcion arbolFicha que
devuelva el árbol con todas las posibles combinaciones que se pueden producir a partir de esa
ficha en ese tablero de dominó. Elige la representación de Arbol que consideres más conveniente,
explicándola previamente en el fichero de la solución. En la figura inferior se muestran algunos
ejemplos. La salida en Haskell dependerá de la representación elegida, puede ser alguna de las
utilizadas en los problemas de clase o de las prácticas.
47
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
4) (1 punto) Las series de dominós se utilizan mucho para tests psicotécnicos. En este caso, las fichas
de dominó se utilizan para que el aspirante demuestre su capacidad para conceptualizar, y para
aplicar el razonamiento sistemático a nuevos problemas, por lo que constituye una buena
medición del factor “g” de inteligencia general (www.psicoactiva.es) . En este problema,
vamos a considerar series de dominós que están en posición horizontal y solo aquellos casos en
los que hay una relación entre las posiciones x y las posiciones y de las fichas. Pueden ser series
infinitas siempre y cuando no haya fichas negativas en la serie.
Se pide implementar la función generarSerie que recibe como entrada, una ficha y dos nombres de
funciones: la función que se aplica entre las XX, la que se aplica entre YY. El resultado de la serie
puede ser una serie infinita, pero no puede ser una serie con números negativos (en este caso la serie
se pararía)
Notas:
- Ahora las series de casillas ya no cumplen las restricciones del juego del dominó,
son series dobles de números.
- La función suma0 deja la casilla igual a la anterior
48
Ejercicios de Examen. Informática. Haskell. Versión curso 2020/2021
49