-
Notifications
You must be signed in to change notification settings - Fork 0
/
examen_6_02_May.hs
128 lines (112 loc) · 5.12 KB
/
examen_6_02_May.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
-- Informática (1º del Grado en Matemáticas, Grupo 1)
-- 6º examen de evaluación continua (2 de mayo de 2012)
-- ---------------------------------------------------------------------
import Data.Array
import Data.List
-- ---------------------------------------------------------------------
-- Ejercicio 1. Un número x es especial si el número de ocurrencia de
-- cada dígito d de x en x^2 es el doble del número de ocurrencia de d
-- en x. Por ejemplo, 72576 es especial porque tiene un 2, un 5, un 6 y
-- dos 7 y su cuadrado es 5267275776 que tiene exactamente dos 2, dos 5,
-- dos 6 y cuatro 7.
--
-- Definir la función
-- especial :: Integer -> Bool
-- tal que (especial x) se verifica si x es un número especial. Por
-- ejemplo,
-- especial 72576 == True
-- especial 12 == False
-- Calcular el menor número especial mayor que 72576.
-- ---------------------------------------------------------------------
especial :: Integer -> Bool
especial x =
sort (ys ++ ys) == sort (show (x^2))
where ys = show x
-- EL cálculo es
-- ghci> head [x | x <- [72577..], especial x]
-- 406512
-- ---------------------------------------------------------------------
-- Ejercicio 2. Definir la función
-- posiciones :: Eq a => a -> Array (Int,Int) a -> [(Int,Int)]
-- tal que (posiciones x p) es la lista de las posiciones de la matriz p
-- cuyo valor es x. Por ejemplo,
-- ghci> let p = listArray ((1,1),(2,3)) [1,2,3,2,4,6]
-- ghci> p
-- array ((1,1),(2,3)) [((1,1),1),((1,2),2),((1,3),3),
-- ((2,1),2),((2,2),4),((2,3),6)]
-- ghci> posiciones 2 p
-- [(1,2),(2,1)]
-- ghci> posiciones 6 p
-- [(2,3)]
-- ghci> posiciones 7 p
-- []
-- ---------------------------------------------------------------------
posiciones :: Eq a => a -> Array (Int,Int) a -> [(Int,Int)]
posiciones x p = [(i,j) | (i,j) <- indices p, p!(i,j) == x]
-- ---------------------------------------------------------------------
-- Ejercicio 3. Definir la función
-- agrupa :: Eq a => [[a]] -> [[a]]
-- tal que (agrupa xss) es la lista de las listas obtenidas agrupando
-- los primeros elementos, los segundos, ... de forma que las longitudes
-- de las lista del resultado sean iguales a la más corta de xss. Por
-- ejemplo,
-- agrupa [[1..6],[7..9],[10..20]] == [[1,7,10],[2,8,11],[3,9,12]]
-- agrupa [] == []
-- ---------------------------------------------------------------------
agrupa :: Eq a => [[a]] -> [[a]]
agrupa [] = []
agrupa xss
| [] `elem` xss = []
| otherwise = primeros xss : agrupa (restos xss)
where primeros = map head
restos = map tail
-- ---------------------------------------------------------------------
-- Ejercicio 4. [Basado en el problema 341 del proyecto Euler]. La
-- sucesión de Golomb {G(n)} es una sucesión auto descriptiva: es la
-- única sucesión no decreciente de números naturales tal que el número
-- n aparece G(n) veces en la sucesión. Los valores de G(n) para los
-- primeros números son los siguientes:
-- n 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ...
-- G(n) 1 2 2 3 3 4 4 4 5 5 5 6 6 6 6 ...
-- En los apartados de este ejercicio se definirá una función para
-- calcular los términos de la sucesión de Golomb.
-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
-- Ejercicio 4.1. Definir la función
-- golomb :: Int -> Int
-- tal que (golomb n) es el n-ésimo término de la sucesión de Golomb.
-- Por ejemplo,
-- golomb 5 == 3
-- golomb 9 == 5
-- Indicación: Se puede usar la función sucGolomb del apartado 2.
-- ---------------------------------------------------------------------
golomb :: Int -> Int
golomb n = sucGolomb !! (n-1)
-- ---------------------------------------------------------------------
-- Ejercicio 4.2. Definir la función
-- sucGolomb :: [Int]
-- tal que sucGolomb es la lista de los términos de la sucesión de
-- Golomb. Por ejemplo,
-- take 15 sucGolomb == [1,2,2,3,3,4,4,4,5,5,5,6,6,6,6]
-- Indicación: Se puede usar la función subSucGolomb del apartado 3.
-- ---------------------------------------------------------------------
sucGolomb :: [Int]
sucGolomb = subSucGolomb 1
-- ---------------------------------------------------------------------
-- Ejercicio 4.3. Definir la función
-- subSucGolomb :: Int -> [Int]
-- tal que (subSucGolomb x) es la lista de los términos de la sucesión
-- de Golomb a partir de la primera ocurrencia de x. Por ejemplo,
-- take 10 (subSucGolomb 4) == [4,4,4,5,5,5,6,6,6,6]
-- Indicación: Se puede usar la función golomb del apartado 1.
-- ---------------------------------------------------------------------
subSucGolomb :: Int -> [Int]
subSucGolomb 1 = 1 : subSucGolomb 2
subSucGolomb 2 = [2,2] ++ subSucGolomb 3
subSucGolomb x = replicate (golomb x) x ++ subSucGolomb (x+1)
-- Nota: La sucesión de Golomb puede definirse de forma más compacta
-- como se muestra a continuación.
sucGolomb' :: [Int]
sucGolomb' = 1 : 2 : 2 : g 3
where g x = replicate (golomb x) x ++ g (x+1)
golomb n = sucGolomb !! (n-1)