PageRenderTime 58ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/exams.hs

http://github.com/jneira/haskell-desk
Haskell | 1118 lines | 416 code | 182 blank | 520 comment | 23 complexity | 77d65a99d72c82b163facf808c4aaf9e MD5 | raw file
  1. module Examen where
  2. import Data.List as List
  3. import Data.Numbers.Primes
  4. import Random
  5. import Control.Arrow
  6. -- EXAMEN SEPT 2009
  7. {-1. Una regla de reescritura puede ser vista como una tupla formada por una
  8. cadena de entrada y una lista de cadenas de salida. Por ejemplo:
  9. reglas = [ ("DESPEDIDA",["ADIOS","NOS VEREMOS"]),
  10. ("HOLA",["ENCANTADO"]),
  11. ("SALUDO",["HOLA","QUE TAL?"]) ]
  12. Asumiremos que en una lista de reglas de reescritura no existen dos reglas
  13. con la misma cadena de entrada. Se pide programar (en HUGS) las
  14. siguientes funciones:
  15. (a) (1 punto) Una funcion reescribe que, dada una cadena c y una lista
  16. de reglas de reescritura r, si en r existe una regla cuya cadena de
  17. entrada coincida con l devuelva la lista de cadenas de salida que establece
  18. dicha regla. Si no existiese una regla tal en r debera devolver
  19. una lista vacia. Por ejemplo:
  20. > reescribe "DESPEDIDA" reglas
  21. ["ADIOS","NOS VEREMOS"]
  22. > reescribe "ADIOS" reglas
  23. []
  24. -}
  25. reglas = [ ("DESPEDIDA",["ADIOS","NOS VEREMOS"]),
  26. ("HOLA",["ENCANTADO"]),("SALUDO",["HOLA","QUE TAL?"]) ]
  27. reescribe c r
  28. | res==[]=[]
  29. | otherwise=snd.head $ res
  30. where res=(filter ((== c).fst)) r
  31. reescribe1 sent [] = []
  32. reescribe1 sent ((ent,sal):resto)
  33. | sent == ent = sal
  34. | otherwise = reescribe1 sent resto
  35. reescribe2 c r= concat [s | (e,s)<-r,e==c]
  36. {-(b) (1,5 puntos) Diremos que una lista de cadenas es irreducible segun una
  37. lista de reglas de reescritura r, si ninguna de sus cadenas es cadena de
  38. entrada para una regla de r. Se desea, pues, una funcion reescritura
  39. que, dada una lista de reglas de reescritura r y una lista de cadenas
  40. l, devuelva la lista de cadenas irreducible resultado de reescribir todas
  41. las cadenas de l segun r (se valorara eficiencia). Por ejemplo:
  42. > reescritura reglas ["SALUDO","SOY UN PROGRAMA","DESPEDIDA"]
  43. ["ENCANTADO","QUE TAL?","SOY UN PROGRAMA","ADIOS","NOS VEREMOS"]-}
  44. reescritura [] r=[]
  45. reescritura (h:s) r
  46. | out==[]=h:reescritura s r
  47. | otherwise=reescritura (out++s) r
  48. where out=reescribe h r
  49. test1=reescritura ["SALUDO","SOY UN PROGRAMA","DESPEDIDA"] reglas
  50. == ["ENCANTADO","QUE TAL?","SOY UN PROGRAMA","ADIOS","NOS VEREMOS"]
  51. {-2. Se pide programar en HUGS las siguientes funciones:
  52. (a) (1 punto) Una funcion extiende que, dada una funcion f::a -> a ->
  53. a y una lista l::[a] extienda la funcion f sobre todos los elementos
  54. de l. Por ejemplo:
  55. >extiende (+) [1..10]
  56. 55
  57. > extiende (++) [[1],[2],[23],[34]]
  58. [1,2,23,34]-}
  59. extiende f (h:[])=h
  60. extiende f (h:t)=f h (extiende f t)
  61. extiende2 f (h:t)=foldr f h t
  62. {-(b) (1 punto) Una funcion extiendeCola que recibe una funcion f::a ->
  63. a -> a, una lista l::[a] y un dato d de tipo a y comprueba si extendiendo
  64. f sobre alguna de las colas de la lista l se puede obtener d.
  65. Por ejemplo:
  66. > extiendeCola (+) [1..10] 15
  67. False (ya que extiende (+) [a..10] != 15 para todo a entre 1 y 10)
  68. > extiendeCola (+) [1..10] 19
  69. True (ya que extiende (+) [9,10] == 19)-}
  70. extiendeCola _ [] _= False
  71. extiendeCola f (h:t) d
  72. | extiende f (h:t)==d =True
  73. | otherwise= extiendeCola f t d
  74. extiendeCola2 _ [x] d = x == d
  75. extiendeCola2 f (x:xs) d = (extiende f (x:xs) == d) || (extiendeCola2 f xs d)
  76. t2 =not $ extiendeCola2 (+) [1..10] 15
  77. t3 =extiendeCola2 (+) [1..10] 19
  78. {-3. Sea la funcion: funcion c p l1 l2 = [c x y| x<-l1 , p x , y<-l2]
  79. (a) (1 punto) Deduzca, razonadamente, el tipo de funcion.-}
  80. funcion :: (a->b->c)->(a->Bool)->[a]->[b]->[c]
  81. funcion c p l1 l2 = [c x y| x<-l1 , p x , y<-l2]
  82. {-(b) (1 punto) Si primo es una funcion que nos dice si un numero natural
  83. es, o no, un numero primo. Calcule, razonadamente, el resultado de
  84. evaluar la siguiente expresion:
  85. funcion (*) primo [1..10] [1..3]
  86. [2,3,5,7,4,6,10,14,6,9,15,21]
  87. (c) (0.5 puntos) Explique, razonadamente, que concepto propio de la programacion
  88. funcional ejemplifica la funcion funcion.
  89. listas de comprehension? funciones de orden superior
  90. 4. Sean las funciones: suma a = foldr (+) 0 [1..a] y fact a = foldr
  91. (*) 1 [1..a]
  92. Consideremos la lista infinita l=[(suma x,fact x)|x<-[0..]]. Se pide
  93. escribir las siguientes funciones en HUGS:
  94. (a) (0.5 puntos) Una funcion siguiente que dado el termino k-esimo (x,y)
  95. de l y k, calcule el siguiente termino de l.-}
  96. suma a = foldr (+) 0 [1..a]
  97. fact a = foldr (*) 1 [1..a]
  98. l=[(suma x,fact x)|x<-[0..]]
  99. sig (x,y) k = (x+(k+1),y*(k+1))
  100. {-(b) (1 punto) Una funcion ll que calcule la lista l utilizando la funcion
  101. siguiente.-}
  102. aux (x,y) z= let res=sig (x,y) z
  103. in (x,y): aux res (z+1)
  104. ll=aux (0,1) 0
  105. lll=map fst $ iterate (\(x,y)->(sig x y,y+1)) ((0,1),0)
  106. {-5. (1.5 puntos) Defina una funcion analizaMaximo que, dada una lista l de
  107. naturales devuelva una tupla con el maximo elemento de l y el numero de
  108. veces que se repite. Por ejemplo:
  109. > analizaMaximo [1,2,3,4,2,3,3,4,2,3,3,1]
  110. (4,2)-}
  111. analizaMaximo xs=
  112. let a (x,y) z | x==z = (x,y+1)
  113. | x<z = (z,1)
  114. | otherwise=(x,y)
  115. in foldl a (0,0) xs
  116. t4 = (4,2)==analizaMaximo [1,2,3,4,2,3,3,4,2,3,3,1]
  117. {-Convocatoria Febrero 2009 - Segunda Semana-}
  118. {-1. (1’5 puntos) El siguiente codigo es una forma basica de implementar una
  119. funcion que calcule el enesimo numero de fibonacci :-}
  120. fibonacci 0 = 1
  121. fibonacci 1 = 1
  122. fibonacci n = ( fibonacci (n-1) ) + ( fibonacci (n-2) )
  123. {-Sin embargo, el coste temporal de esta funcion es exponencial. Se pide
  124. escribir una implementacion equivalente que calcule el enesimo numero de
  125. fibonacci de forma eficiente.-}
  126. fib 0 = 1
  127. fib 1 = 1
  128. fib n=let a (h:h':t) _=(h+h':h:h':t)
  129. in head $ foldl a [1,1] [2..n]
  130. fib2 n = ifibonacci n 1 1
  131. where ifibonacci 0 nm1 nm2 = nm2
  132. ifibonacci n nm1 nm2 = ifibonacci (n-1) (nm1+nm2) nm1
  133. {-2. Las ternas pitagoricas son aquellas tuplas (a,b,c) que cumplen
  134. el teorema de pitagoras: a2 +b2 = c2. Se pide programar en HUGS, en una
  135. unica linea y utilizando listas por comprension una funcion que nos devuelva
  136. todas las ternas pitagoricas.-}
  137. pit=[(b,c,a)|a<-[1..],b<-[1..a],c<-[1..b],a^2==b^2+c^2]
  138. pit2 = [(x,y,z) | x <- [1..] , y <- [1..x] , z <- [1..x+y], z*z == x*x + y*y ]
  139. {-3. (1 punto) Dos funciones son equivalentes cuando a igual entrada, devuelven
  140. igual salida. Comprobar esto de forma automatica es, en general, semidecidible,
  141. aunque si restringimos el conjunto de los datos de entrada es perfectamente
  142. posible hacerlo. Se pide, por tanto, programar en HUGS una
  143. funcion equivalentes que recibe dos funciones f y g y una lista de datos l
  144. y comprueba si f y g son equivalentes sobre el conjunto de datos contenido
  145. en l.-}
  146. eqs f g l=(map f l)==(map g l)
  147. {-4. Una funcion muy util a la hora de trabajar con cadenas de caracteres es la
  148. funcion tr, que recibe dos listas de caracteres y una cadena y devuelve la
  149. cadena recibida en la que se han sustituido los caracteres presentes en la
  150. primera lista por los de la segunda (siempre que esten en la misma posicion).
  151. Por ejemplo, para intercambiar los caracteres ’€™ y ’€™ seria:
  152. > tr "ao" "oa" "hola mundo"
  153. "halo munda"
  154. (a) (1 punto) Se pide implementar una funcion tr generica, que realice lo
  155. anteriormente descrito.-}
  156. tr' x y []=[]
  157. tr' x y (h:t)
  158. | x==h = y: tr' x y t
  159. | otherwise=h:tr' x y t
  160. tr [] ys cad=cad
  161. tr xs [] cad=cad
  162. tr (hx:tx) (hy:ty) cad=
  163. tr tx ty (tr' hx hy cad)
  164. tr2 xs ys cad=
  165. let itr [] ys x=x
  166. itr xs [] x=x
  167. itr (h:t) (h':t') x
  168. | h==x = h'
  169. | otherwise=itr t t' x
  170. in map (itr xs ys) xs
  171. {-(b) (1 punto) ¿Que concepto de la programacion funcional se esta utilizando
  172. en la funcion anterior? Expliquelo y ponga algun otro ejemplo.
  173. Se supone que la recursividad en mi caso, patrones estructurales en fin.
  174. -}
  175. {-5. (1 punto) Dada una lista de numeros, se pide programar en HUGS una
  176. funcion diferencias que devuelva la lista de diferencias entre dos elementos
  177. consecutivos de la lista de entrada. Por ejemplo:
  178. > diferencias [1,4,9,16,25,36]
  179. [3,5,7,9,11]-}
  180. diferencias xs=
  181. let itr x (0,[])=(x,[])
  182. itr x (pre,acc)=(x,(pre-x):acc)
  183. in snd $ foldr itr (0,[]) xs
  184. diferencias2 (h:t)=
  185. let dif [] x=[]
  186. dif (h:t) x=(h-x):dif t h
  187. in dif t h
  188. t6= diferencias2 [1,4,9,16,25,36]
  189. {-6. Se pide programar en HUGS las siguientes funciones:
  190. (a) (075 puntos) Una funcion decimales que, dados dos numeros naturales
  191. a y b nos devuelva la lista infinita de los decimales (incluyendo
  192. la parte entera) de la division a/b. Por ejemplo:
  193. > decimales 146 7
  194. [20,8,5,7,1,4,2,8,5,7,1,4,2,...]-}
  195. dec a b=
  196. let (d,r)=(div a b,(mod a b)*10)
  197. in d:dec r b
  198. {-(b) (075 puntos) Una funcion restos que, dados dos numeros naturales
  199. a y b nos devuelva la lista infinita de los sucesivos restos obtenidos al
  200. realizar la division a/b. Por ejemplo:
  201. > restos 146 7
  202. [6,4,5,1,3,2,6,4,5,1,3,2,6,...]-}
  203. restos a b=
  204. let r=mod a b
  205. in r:restos (r*10) b
  206. {-(c) (15 puntos) Una funcion periodo que, dados dos numeros naturales
  207. a y b nos devuelva el periodo de la expresion decimal a/b. Para ello
  208. utilice las funciones decimales y restos realizadas anteriormente.
  209. El periodo comienza cuando aparece por primera vez el primer resto
  210. repetido y termina justo antes de aparecer dicho resto por segunda
  211. vez. Fijandonos en los ejemplos anteriores, el primer resto repetido es
  212. el 6 y la longitud del periodo es, tambien, 6. Por lo tanto, el periodo
  213. seria:
  214. [20,8,5,7,1,4,2,8,5,7,1,4,2,...]
  215. > periodo 146 7
  216. [8,5,7,1,4,2]-}
  217. patron _ xs []=[]
  218. patron max [] (h:t)=patron max [h] t
  219. patron max xs (h:t)
  220. | l>max =[]
  221. | xs==next=xs
  222. | otherwise= patron max (xs++[h]) t
  223. where l=length xs
  224. next=take l (h:t)
  225. periodo a b=
  226. let (hd:td)=dec a b
  227. itr h (h':t')
  228. | null p=itr h' t'
  229. | otherwise=p
  230. where p=patron 10 [h] (h':t')
  231. in itr hd td
  232. {-Convocatoria Febrero 2009 - Primera Semana
  233. 1. Diremos que un numero es especial si dicho numero es igual a la suma
  234. de los factoriales de sus cifras. Por ejemplo, tenemos que 145 = 1!+4!+5!.
  235. Supongamos que tenemos ya una funcion fact que nos devuelve el factorial
  236. de un numero. Se pide programar (en HUGS) las siguientes funciones:
  237. (a) (15 puntos) Una funcion especial que, dado un numero natural n nos
  238. indica si dicho numero es, o no, especial. (Nota: Se pueden utilizar
  239. tantas funciones auxiliares como se consideren necesarias)-}
  240. numLista 0=[]
  241. numLista n=
  242. let (d,r)=(div n 10,mod n 10)
  243. in numLista d++[r]
  244. especial n=n==(sum $ map fact $ numLista n)
  245. especiales=filter especial [1..]
  246. {-(b) (05 puntos) Una funcion especiales que, dados dos numeros naturales
  247. a y b, nos devuelve todos los n´umeros especiales entre a y b ambos
  248. inclusive.
  249. Para resolver este apartado utilizaremos la funcion filter que nos
  250. filtra los elementos de una lista que cumplen una cierta condicion. En
  251. este caso la de ser numeros especiales:-}
  252. esps a b=filter especial [a..b]
  253. {-2. (1 punto) Se pide programar en HUGS una funcion aplicar, que recibe
  254. un numero natural n, una funcion f :: a -> a y un valor x :: a y
  255. devuelve el resultado de aplicar n veces la funcion f a x. Por ejemplo, si f
  256. x = x + 1, entonces:
  257. > aplicar 0 f 4
  258. 4
  259. > aplicar 1 f 4
  260. 5
  261. > aplicar 5 f 4
  262. 9-}
  263. aplicar n f a=last.(take (n+1))$ (iterate f a)
  264. aplicar2 0 f a=a
  265. aplicar2 n f a=f (aplicar2 (n-1) f a)
  266. {-3. (15 puntos) El siguiente codigo es una posible forma de implementar el
  267. algoritmo de ordenacion Quicksort:-}
  268. quicksort [] = []
  269. quicksort (a:x) = (quicksort menores) ++ [a] ++ (quicksort mayores)
  270. where menores = filter (< a) x
  271. mayores = filter (not . (< a)) x
  272. {-Se pide escribir una implementacion equivalente que calcule las listas mayores
  273. y menores de una forma mas eficiente que el codigo aqui presentado.-}
  274. quicksort2 [] = []
  275. quicksort2 (a:x) = (quicksort2 menores) ++ [a] ++ (quicksort2 mayores)
  276. where (menores,mayores) = minmax a x
  277. minmax a xs=
  278. let acc (min,may) x
  279. | x<a=(x:min,may)
  280. | otherwise=(min,x:may)
  281. in foldl acc ([],[]) xs
  282. rands x=take x $ randomRs (1,20) (mkStdGen 42)
  283. {-4. Las Maquinas Pila son maquinas virtuales que permiten ejecutar instrucciones
  284. sencillas que operan sobre una pila. Por ejemplo, para sumar dos
  285. numeros a y b, primero se apilaria uno, despues el otro y luego se ejecutarıa
  286. la instruccion Sumar, que desapilarıa los dos ultimos numeros apilados en
  287. la pila, los sumarıa y apilarıa el resultado nuevamente en la pila.
  288. Se pide programar en HUGS una sencilla maquina pila que permita ejecutar
  289. programas con sumas, restas, multiplicaciones y divisiones sobre numeros
  290. enteros. Para ello:
  291. (a) (15 puntos) Diseñe una implementacion de una pila utilizando listas.
  292. Implemente las operaciones basicas para trabajar con pilas utilizando
  293. la implementacion que ha diseñado: pilavacia, apilar, desapilar
  294. y cima.-}
  295. pilavacia=[]
  296. apilar h t=h:t
  297. desapilar []=(0,[])
  298. desapilar (h:t)=(h,t)
  299. cima (h:t)=h
  300. {-(b) (15 puntos) Implemente las funciones sumar, restar, multiplicar
  301. y dividir que dada una pila p devuelven otra pila en la que se han
  302. desapilado los dos ultimos elementos apilados en p y se ha apilado
  303. la operacion correspondiente (suma, resta, multiplicacion o division)
  304. entre ellos.-}
  305. eval op p=
  306. let (op1,p1)=desapilar p
  307. (op2,p2)=desapilar p1
  308. in apilar (op op1 op2) p2
  309. psuma p=eval (+) p
  310. presta p=eval (-) p
  311. pmult p=eval (*) p
  312. pdiv p=eval div p
  313. {-(c) (05 puntos) Defina un tipo de datos Instrucciones que contenga las
  314. instrucciones de la maquina pila. Dichas instrucciones deben permitir
  315. apilar un numero entero y realizar las cuatro operaciones basicas
  316. anteriormente descritas.-}
  317. data Instr=Sumar | Restar | Mult | Div | Apilar Int
  318. deriving (Show)
  319. {-(d) (1 punto) Implemente una funcion ejecutarcodigo a la cual se le
  320. pase una lista de Instrucciones c y una pila p, y devuelva la pila
  321. resultante de ejecutar el codigo almacenado en c. Por ejemplo, si la
  322. lista fuese [Apilar 4,Apilar 3,Apilar 2,Sumar,Multiplicar], se
  323. devolveria una pila en cuya cima se encontraria el resultado de evaluar
  324. la expresion 4 * (3 + 2).-}
  325. ejecutarCodigo [] p=p
  326. ejecutarCodigo (h:t) p=
  327. let op Sumar=psuma ; op Restar=presta
  328. op Mult=pmult ; op Div=pdiv ;
  329. op (Apilar x)=(apilar x)
  330. in ejecutarCodigo t (op h $ p)
  331. test=ejecutarCodigo [Apilar 4,Apilar 3,Apilar 2,Sumar,Mult] []
  332. {-5. (1 punto) Explique el concepto de evaluacion perezosa utilizando como
  333. ejemplo alguna funcion de las que se pide implementar en este examen.
  334. *La eval perezosa consiste en que la evaluacion se pospone hasta que el
  335. resultado de la misma es necesaria. Eso posibilita crear funciones
  336. que representen valores infinitos
  337. Convocatoria Septiembre 2008 - Original
  338. 1. El juego del Tetris consiste en ir colocando una serie de piezas que caen en
  339. un tablero bidimensional, de forma que al llenar una fila esta desaparece.
  340. El juego termina cuando la fila superior del tablero no esta vacia. Para representar
  341. el tablero se puede utilizar una matriz bidimensional de naturales,
  342. representando cada numero el color de las piezas salvo el 0 que representar´ıa
  343. un espacio en blanco. Se pide programar en HUGS:
  344. (a) (1 punto) Una funcion nuevoTablero que, dados dos numeros enteros
  345. ancho y alto mayores que cero, cree un tablero vacio para jugar al
  346. Tetris.-}
  347. nuevoTablero x y=replicate x (replicate y 0)
  348. {-(b) (15 puntos) Las funciones filaLlena, filaNoLlena, filaVacia, filaNoVacia
  349. que dada una fila del tablero nos digan, respectivamente, si dicha
  350. fila esta llena, no lo esta, esta vacia o no lo esta.-}
  351. filaLlena=and.(map (/= 0))
  352. filaVacia=and.(map (== 0))
  353. filaNoLlena=not.filaLlena
  354. filaNoVacia=not.filaVacia
  355. {-(c) (05 puntos) Una funcion gameOver que, dado un tablero, nos diga si
  356. el juego debe o no terminar.-}
  357. gameOver=filaLlena.head
  358. {-(d) (1 punto) Una funcion numeroDeLineas que, dado un tablero, nos diga
  359. cuantas filas estan llenas en dicho tablero.-}
  360. numLineasLlenas tb=length $ filter (filaLlena) tb
  361. {-(e) (15 puntos) Una funcion cambiaTablero que, dado un tablero, nos
  362. devuelva otro tablero (del mismo tamaño) en el que se hayan eliminado
  363. las filas llenas, desplazando hacia abajo las que estuvieran por encima
  364. de estas.-}
  365. cambioTablero []=[]
  366. cambioTablero (h:t)
  367. | filaLlena h = fv:cambioTablero t
  368. | otherwise=h:cambioTablero t
  369. where fv=replicate (length h) 0
  370. {-2. Se dice que un numero es omirp cuando se trata de un numero primo y
  371. ademas al invertir sus digitos tambien se obtiene un numero primo. Por
  372. ejemplo 31 es omirp pues 13 tambien es primo, de igual forma 1597 y 7951
  373. son tambien numeros omirp. Se pide programar en HUGS:
  374. (a) (1 punto) Una funcion invierteNumero que dado un numero natural x
  375. mayor que cero, devuelva el numero natural resultado de invertir los
  376. digitos de x.-}
  377. numLista2 0=[]
  378. numLista2 x=
  379. let (d,r)=(div x 10, mod x 10)
  380. in (numLista2 d)++[r]
  381. calc x y z=x*y+z
  382. listaNum2 =foldl (calc 10) 0
  383. invNum n=listaNum2 $ reverse $ numLista2 n
  384. invierteNumero x = iInvierteNumero 0 x
  385. where iInvierteNumero ac 0 = ac
  386. iInvierteNumero ac x = iInvierteNumero (ac*10+u) d
  387. where u = mod x 10
  388. d = div x 10
  389. {-(b) (05 puntos) Suponiendo que tenemos una funcion primo que nos dice
  390. si un numero es primo, se desea una funcion omirp que dado un numero
  391. natural x, nos diga si dicho numero es, o no, omirp.-}
  392. omirp n=isPrime n && (isPrime $ invNum n)
  393. {-3. Un fichero puede ser vacio o bien contener un documento de texto o una
  394. carpeta, la cual puede contener a su vez un numero arbitrario de ficheros.
  395. Se pide realizar en HUGS:
  396. (a) (05 puntos) Definir una estructura que sea capaz de representar un
  397. fichero.-}
  398. data Fichero=Vacio | Texto [Char] | Carpeta [Fichero]
  399. deriving (Show)
  400. {-(b) (15 puntos) Las funciones numTextos y numCarpetas que devuelven,
  401. respectivamente, el numero de documentos de texto y el numero de
  402. carpetas que contiene un fichero.-}
  403. numTextos Vacio = 0
  404. numTextos (Texto x) = 1
  405. numTextos (Carpeta fics)= sum $ map numTextos fics
  406. numCarpetas Vacio=0
  407. numCarpetas (Texto x)=0
  408. numCarpetas (Carpeta fics)=1+(sum $ map numCarpetas fics)
  409. {-(c) (1 punto) Una funcion sacaTextos que dado un fichero, nos devuelva
  410. otro fichero obtenido eliminando todos los documentos de texto del
  411. fichero de entrada.-}
  412. sacaTextos (Texto x)=Vacio
  413. sacaTextos (Carpeta fics)=Carpeta (map sacaTextos fics)
  414. sacaTextos fic=fic
  415. test6=sacaTextos (Carpeta [Vacio,Texto "hola",Carpeta [Texto "adios"]])
  416. -- >Carpeta [Vacio,Vacio,Carpeta [Vacio]]
  417. {-Convocatoria Febrero 2008 - Segunda Semana-}
  418. {-1. Queremos disponer en HUGS de un tipo de datos que permita expresar funciones
  419. como combinaciones de sumas, restas, productos y divisiones de polinomios.
  420. Para ello:
  421. (a) (1 punto) Defina el tipo de datos Funcion que permita expresar una
  422. funcion como combinacion de sumas, restas, productos o divisiones
  423. de polinomios con coeficientes reales (para representar un polinomio
  424. utilice una lista de numeros reales que contenga sus coeficientes).-}
  425. data OperP=SumaP|RestaP|ProdP|DivP deriving (Show)
  426. data Funcion= Polinomio [Float] | Funcion OperP (Funcion) (Funcion)
  427. deriving (Show)
  428. {-(b) (15 puntos) Diseñe una funcion evalua que, dada f de tipo Funcion
  429. y un numero real x, evalue f en x.-}
  430. evalua (Funcion SumaP f g) x= (evalua f x) + (evalua g x)
  431. evalua (Funcion RestaP f g) x= (evalua f x) - (evalua g x)
  432. evalua (Funcion ProdP f g) x= (evalua f x) * (evalua g x)
  433. evalua (Funcion DivP f g) x= (evalua f x) / (evalua g x)
  434. evalua (Polinomio []) x=0
  435. evalua (Polinomio (h:t)) x=h+ x * evalua (Polinomio t) x
  436. {-(c) (15 puntos) Diseñe una funcion derivada que, dada f de tipo Funcion,
  437. devuelva la funcion derivada de f como un dato de tipo Funcion.
  438. Recuerde que:
  439. (f + g)' = f' + g'
  440. (f g)' = f' g'
  441. (f * g)' = f' * g + f * g'
  442. (f / g)' = (f'*g+f*g')/g2
  443. (k * x^n)' = n * k * x^(n−1) -}
  444. derivada (Funcion SumaP f g)=Funcion SumaP (derivada f) (derivada g)
  445. derivada (Funcion RestaP f g)=Funcion RestaP (derivada f) (derivada g)
  446. derivada (Funcion ProdP f g)=Funcion SumaP (Funcion ProdP (derivada f) g)
  447. (Funcion ProdP f (derivada g))
  448. derivada (Funcion DivP f g)=
  449. Funcion DivP
  450. (Funcion SumaP
  451. (Funcion ProdP (derivada f) g)
  452. (Funcion ProdP f (derivada g)))
  453. (Funcion ProdP g g)
  454. derivada (Polinomio xs)= Polinomio ( derivadaPol xs 0 [])
  455. derivadaPol [] _ d
  456. | d == [] = [0]
  457. | deriv == [] = [0]
  458. | otherwise = deriv
  459. where deriv = tail d
  460. derivadaPol (x:xs) g d = derivadaPol xs (g+1) (d++[x*g])
  461. {-2. Se desea una funcion en HUGS que, dada una lista l nos devuelva una de las
  462. siguientes cadena de caracteres que describa correctamente a l :
  463. La lista no tiene elementos
  464. La lista tiene un unico elemento
  465. La lista tiene mas de un elemento
  466. (a) (1 punto) Diseñe una funcion que realice eficientemente este cometido.-}
  467. mensaje []="La lista no tiene elementos"
  468. mensaje [a]="La lista tiene un unico elemento"
  469. mensaje xs="La lista tiene mas de un elemento"
  470. {-(b) (05 puntos) Para realizar eficientemente este calculo, ¿que concepto
  471. propio de la programacion funcional estamos aprovechando? Explique
  472. en que consiste dicho concepto comparando la funcion del apartado
  473. anterior con otra funcion que realice el mismo calculo de forma poco
  474. eficiente.
  475. La evaluacion segun patrones estructurales de los datos en lugar de sus valores
  476. En este caso aprovechando la estructura de defincion de una lista
  477. Evaluacion perezosa ya que no se evalua mas que la parte de la
  478. lista necesaria.
  479. 3. Realice las siguientes funciones en HUGS en una unica linea de codigo:
  480. (a) (05 puntos) Una funcion aListas que, dada una lista de naturales,
  481. devuelva otra lista en la que cada elemento sea una lista que contenga
  482. tantas listas vacias como indique el elemento correspondiente de la
  483. lista de entrada. Por ejemplo:
  484. > aLista [0,1,2,3]
  485. [[],[[]],[[],[]],[[],[],[]]]-}
  486. aLista=map (flip replicate$ [])
  487. {-(b) (05 puntos) Una funcion aNaturales que realice el proceso inverso al
  488. realizado por aListas.-}
  489. aNaturales=map length
  490. {-(c) (05 puntos) Una funcion que, dada una lista l como las producidas
  491. por la funcion aListas, realice el mismo calculo que:-}
  492. calc1 l=foldr (+) 0 (aNaturales l)
  493. calc2 l=foldl (+) 0 (aNaturales l)
  494. calc3 l=length ( concat l )
  495. {-4. Un punto en un espacio n-dimensional se puede representar como una lista
  496. de n numeros reales con las coordenadas de dicho punto respecto de un
  497. sistema de referencia dado. Se pide programar las siguientes funciones en
  498. HUGS:
  499. (a) (05 puntos) Una funcion igualdimension que, dadas dos listas, nos
  500. diga si ambas tienen la misma longitud. Para realizar esta funcion no
  501. debera utilizarse la funcion predefinida length ni programar
  502. otra que realice su funcion. -}
  503. igualdim [] []=True
  504. igualdim [] ys=False
  505. igualdim xs []=False
  506. igualdim (h:t) (h':t')=igualdim t t'
  507. {-(b) (1 punto) Una funcion distancia que, dados dos puntos en un espacio
  508. n-dimensional, calcule la distancia euclidea (por ejemplo, en dimension
  509. 2, la distancia entre [2,1] y [3,4] es la raiz cuadrada de (23)^2+(14)^2)
  510. entre dichos puntos. Esta funcion debera devolver -1 en el caso de que
  511. los puntos no pertenezcan al mismo espacio (es decir, que la longitud
  512. de ambas listas sea diferente).-}
  513. distancia xs ys
  514. | (igualdim xs ys)=sum $ map (\[x,y]->(x-y)^2) (transpose [xs,ys])
  515. | otherwise=(-1)
  516. distancia2 [] []=0
  517. distancia2 xs []=(-1)
  518. distancia2 [] ys=(-1)
  519. distancia2 (h:t) (h':t')=((h-h')^2)+distancia2 t t'
  520. {-(c) (15 puntos) Una funcion longitud que, dada una lista de puntos en
  521. un espacio n-dimensional, calcule la longitud del camino que forman,
  522. como suma de las distancias entre dos puntos consecutivos. Si alguno
  523. de los puntos no estuviera en el mismo espacio que los demas (alguna
  524. lista es de diferente longitud), esta funcion debera devolver -1.-}
  525. long []=0
  526. long (h:t)=
  527. let r (acc,p) p'
  528. | (igualdim p p' && acc>=0)=(acc+distancia p p',p')
  529. | otherwise= (acc,p)
  530. in fst $ foldl r (0,h) t
  531. long1 []=0
  532. long1 [a]=0
  533. long1 (p:p':t)
  534. | (d>=0) && (l>=0) =d+l
  535. | otherwise=(-1)
  536. where d= distancia p p'
  537. l=long1 t
  538. {-Convocatoria Febrero 2008 - Primera Semana-}
  539. {-1. Supongamos tener una funcion mayor (que define un orden parcial) que
  540. dados dos elementos x e y de tipo a nos dice si x es mayor que y. Nuestro
  541. objetivo es, dada una lista de elementos de tipo a, obtener dicha lista
  542. ordenada segun el orden definido por la funcion mayor, de forma que si se
  543. cumple que mayor x y, entonces y debe preceder a x en la lista resultado.
  544. Se pide programar en HUGS las siguientes funciones:
  545. (a) (15 puntos) Una funcion inserta que, dada una funcion mayor, un elemento
  546. x de tipo a y una lista l de elementos del mismo tipo (ordenada
  547. segun el orden establecido por la funcion mayor), inserte ordenadamente
  548. x en l, siguiendo el orden que establece la funcion mayor.-}
  549. inserta _ x []=[x]
  550. inserta mayor x (h:t)
  551. | mayor x h=h:(inserta mayor x t)
  552. | otherwise=x:h:t
  553. {-(b) (15 puntos) Una funcion ordena que, dada una funcion mayor y una
  554. lista l de elementos, devuelva la lista l ordenada segun el orden establecido
  555. por la funcion mayor. Utilice, para ello, la funcion inserta
  556. del apartado anterior-}
  557. ordena mayor []=[]
  558. ordena mayor xs=ordena' mayor [] xs
  559. ordena' mayor xs []=xs
  560. ordena' mayor xs (h:t)=ordena' mayor (inserta mayor h xs) t
  561. {-2. (15 puntos) ¿Que conceptos propios de la programacion funcional ilustran
  562. las funciones del ejercicio anterior? Expliquelo tomando como ejemplos las
  563. funciones inserta y ordena.
  564. funciones de orden superior
  565. Definicion de funciones con patrones
  566. El patr´on subrayado
  567. Uso de listas-}
  568. {-3. Se dice que dos numeros son amigos si la suma de los divisores propios (todos
  569. sus divisores salvo el mismo) del primero es igual al segundo y viceversa.
  570. Por ejemplo:
  571. los divisores propios de 220 son 1, 2, 4, 5, 10, 11, 20, 22, 44, 55 y 110, que
  572. suman 284
  573. los divisores propios de 284 son 1, 2, 4, 71 y 142, que suman 220
  574. Se pide programar las siguientes funciones en HUGS, cada una en una
  575. ´unica linea de codigo:
  576. (a) (05 puntos) Una funcion suma que sume los elementos de una lista
  577. de numeros.-}
  578. sumaN xs=foldl1 (+) xs
  579. {-(b) (05 puntos) Una funcion divisores que genere la lista de los divisores
  580. propios de un numero.-}
  581. divs n=filter (\x->(mod n x)==0) [1..(div n 2)]
  582. divs2 n=[x | x<-[1..(div n 2)],(mod n x)== 0]
  583. {-(c) (05 puntos) Una funcion amigos que dados dos numeros nos diga si
  584. son numeros amigos.-}
  585. amigos x y=(sumaN $ divs x) == y &&
  586. (sumaN $ divs y) == x
  587. {-4. (1 punto) Realice una funcion esFactorial (en HUGS) que dado un numero
  588. natural, nos diga si es, o no, el factorial de otro numero y, en caso de serlo,
  589. nos devuelva dicho numero.-}
  590. esFactorial f x
  591. | factorial x==f=f
  592. | otherwise=(-1)
  593. factorial 0=1
  594. factorial 1=1
  595. factorial x=x*(factorial (x-1))
  596. iesFactorial n c fc
  597. | n == fc = (True,c)
  598. | n < fc = (False,0)
  599. | otherwise = iesFactorial n (c+1) (fc*(c+1))
  600. esFactorial2 n = iesFactorial n 1 1
  601. {-5. (1 punto) La programacion funcional pura nos permite escribir un programa
  602. sin que importe el orden en el que se definen las funciones. Sin embargo,
  603. en algunas ocasiones el orden de escritura si resulta importante. Ilustre con
  604. un ejemplo como podria variar la evaluacion de una funcion si cambiasemos
  605. el orden de escritura de su definicion.
  606. Una funcion que genere numeros aleatorios sera diferente en un orden u otro
  607. 6. Las Maquinas de Turing y otros modelos computacionales utilizan estructuras
  608. de datos denominadas cintas, que consisten en secuencias de valores
  609. arbitrariamente largas. Para acceder a estas cintas existe un puntero que
  610. indica en que posicion de la cinta se encuentra el siguiente dato a leer o
  611. escribir.
  612. (a) (05 puntos) Defina un tipo de datos Cinta que permita almacenar,
  613. de forma eficiente, una cinta de datos y el puntero de la misma.-}
  614. data Cinta a = Cinta [a] [a] deriving (Show)
  615. {-(b) (1 punto) Implemente dos funciones avanza y retrocede que dada una
  616. cinta c devuelvan una cinta en las que el puntero se haya movido al
  617. siguiente dato y al anterior respectivamente.-}
  618. avanza (Cinta [a] [])=Cinta [a] []
  619. avanza (Cinta [a] [hp:tp])=Cinta [hp:a] [tp]
  620. retrocede (Cinta [] [p])=Cinta [] [p]
  621. retrocede (Cinta [ha:ta] [p])=Cinta [ta] [ha:p]
  622. {-(c) (05 puntos) Implemente una funcion nuevoDato que dada una cinta c
  623. y un dato d, devuelva otra cinta igual a c salvo que el dato apuntado
  624. por el puntero haya sido substituido por d.
  625. S-}
  626. nuevoDato (Cinta [a] [p]) d=Cinta [a] [d:p]
  627. {-Convocatoria Septiembre 2007 - Original
  628. 1. (15 puntos) La especificacion de una funcion se compone de:
  629. Precondicion: predicado que define las condiciones que deben cumplir
  630. los datos de entrada
  631. Postcondicion: predicado que define la relacion entre los datos de entrada
  632. y los datos de salida
  633. Se desea una funcion test en HUGS que, dada una funcion, su especificacion
  634. y un dato de entrada para dicha funcion, nos diga si la funcion, para ese
  635. dato de entrada, cumple con su especificacion.-}
  636. testf f (pre,post) d=not.pre $ d || (post d $ f d)
  637. {-2. (15 puntos) Se desea una funcion quitaPareja en HUGS que, dados dos
  638. elementos a y b y una lista xs, devuelva la lista resultante de eliminar de
  639. xs toda aparicion consecutiva (y en el mismo orden) de los elementos a y
  640. b. Por ejemplo:
  641. > quitaPareja 12 10 [1,2,10,12,10,20,12,10,10,12]
  642. [1,2,10,20,10,12]-}
  643. quitaPareja a b []=[]
  644. quitaPareja a b [c]=[c]
  645. quitaPareja a b (h:h':t)
  646. | a==h && b==h' =quitaPareja a b t
  647. | otherwise=h:quitaPareja a b (h':t)
  648. t5=quitaPareja 12 10 [1,2,10,12,10,20,12,10,10,12]==[1,2,10,20,10,12]
  649. {-3. Se desea una funcion en HUGS que, dado un numero natural, obtenga su
  650. descomposicion segun unos factores determinados. Para ello:
  651. (a) (1 punto) Programe una funcion factor que, dado un numero n y un
  652. factor x, devuelva una tupla formada por el numero de veces que x
  653. divide a n y el resultado de dividir n por x elevado a dicho numero.
  654. Por ejemplo:
  655. > factor 3 162
  656. (4,2)
  657. Ya que 162 = 2*3^4.-}
  658. factor a n=
  659. let nxt (x,y)=(x+1,div y a)
  660. in until (\(x,y)->(mod y a)/=0) nxt (0,n)
  661. factor2 :: (Num a, Integral b) => (b,b) -> (a,b)
  662. factor2 (x,n) = ifactor x (0,n)
  663. where ifactor x (e,n)
  664. | rem n x == 0 = ifactor x (e+1,div n x)
  665. | otherwise = (e,n)
  666. q3a (x,n) = x > 0 && n > 0
  667. r3a (x,n) (p,r) = x^p*r == n
  668. {-(b) (1 punto) Utilizando la funcion factor del apartado anterior, programe
  669. una funcion factoriza que, dado un numero y una lista infinita de
  670. factores, devuelva una lista conteniendo la factorizacion del numero
  671. segun los factores de la lista. Por ejemplo, si listaPrimos devuelve
  672. la lista infinita de los numeros primos, entonces:
  673. > factoriza 327675 listaPrimos
  674. [(3,1),(5,2),(17,1),(257,1)]
  675. Ya que 327675 = 3^1* 5^2* 17^1* 257^1.-}
  676. factoriza x (h:t)
  677. | x==1 = []
  678. | exp==0 = factoriza x t
  679. | otherwise=(h,exp):factoriza r t
  680. where (exp,r)= factor h x
  681. {-4. (15 puntos) Se desea una funcion que dada una lista xs y un predicado
  682. p sobre los elementos de dicha lista, devuelva una tupla formada por dos
  683. listas: la de aquellos elementos que cumplen p y la de los que no lo cumplen.
  684. Por ejemplo, si esPrimo es una funcion que nos dice si un numero es, o no,
  685. primo, entonces:
  686. > separa [1..10] esPrimo
  687. ([2,3,5,7],[1,4,6,8,9,10])
  688. No debe usar ninguna funcion predefinida en HUGS para resolver
  689. el ejercicio. Se valorara la eficiencia de la funcion obtenida.-}
  690. separa [] pred=([],[])
  691. separa xs pred=
  692. let aux (fs,ts) []=(fs,ts)
  693. aux (fs,ts) (h:t)
  694. | pred h=aux (h:fs,ts) t
  695. | otherwise=aux (fs,h:ts) t
  696. in aux ([],[]) xs
  697. {-5. La sucesion de Farey de orden n es la sucesion creciente de todas
  698. las fracciones irreducibles con valores entre 0 y 1 que tienen un denominador
  699. menor o igual a n. Para calcular la sucesion de Farey de orden n + 1
  700. partimos de la sucesion de orden n y añadimos entre cada dos elementos
  701. consecutivos una nueva fraccion cuyo numerador y denominador sean, respectivamente,
  702. la suma de los numeradores y la suma de los denominadores
  703. de dichos elementos, siempre que el nuevo denominador sea menor o igual
  704. a n.
  705. Por ejemplo, representando las fracciones como una tupla (numerador, denominador),
  706. las sucesiones de Farey de orden 1, 2, 3 y 4 serian:
  707. Orden 1: [(0,1),(1,1)] (por definicion)
  708. Orden 2: [(0,1),(1,2),(1,1)]
  709. Orden 3: [(0,1),(1,3),(1,2),(2,3),(1,1)]
  710. Orden 4: [(0,1),(1,4),(1,3),(1,2),(2,3),(3,4),(1,1)]
  711. indicando en negrita aquellas fracciones que aparecen por primera vez.
  712. (a) (2 puntos) Programe una funcion trFarey que, dado un orden n y la
  713. sucesion de Farey de orden n1, calcule la sucesion de Farey de orden
  714. n.-}
  715. trFarey [] _=[]
  716. trFarey [a] _=[a]
  717. trFarey ((a,b):(c,d):t) n
  718. | n==0 = (a,b): r
  719. | otherwise=(a,b):(x,y):r
  720. where (x,y)=(a+c,b+d)
  721. r=trFarey ((c,d):t) (n-1)
  722. {-(b) (15 puntos) Programe una funcion farey que, dado un numero n,
  723. calcule la sucesion de Farey de orden n. Utilice, para ello, la funcion
  724. trFarey del apartado anterior.-}
  725. farey n=
  726. let nxt (xs,x)=(trFarey xs (x+1),x+1)
  727. in fst $ until ((== n).snd) nxt ([(0,1),(1,1)],1)
  728. {-Convocatoria Febrero 2007 - Segunda Semana
  729. 1. (15 puntos) Un numero natural se dice polidivisible si es divisible por su
  730. longitud y al eliminar la cifra de las unidades volvemos a obtener un numero
  731. polidivisible. Por ejemplo:
  732. 1024 sera polidivisible si es divisible por 4 (lo es) y 102 es polidivisible
  733. 102 sera polidivisible si es divisible por 3 (lo es) y 10 es polidivisible
  734. 10 sera polidivisible si es divisible por 2 (lo es) y 1 es polidivisible
  735. 1 es, trivialmente, polidivisible
  736. Por lo tanto 10, 102 y 1024 son numeros polidivisibles
  737. Se desea una funcion en HUGS que, dado un numero natural n > 0 nos diga
  738. si n es, o no, polidivisible.-}
  739. lengthNum x=
  740. let nxt (i,n)=(i+1,div n 10)
  741. in fst $ until ((== 0).snd) nxt (0,x)
  742. lengthNum2:: Integer -> Int
  743. lengthNum2=length.show
  744. lengthNum3 n
  745. | n < 10 = 1
  746. | otherwise = 1 + lengthNum3 ( div n 10 )
  747. esPolidiv 1=True
  748. esPolidiv x=(0==(mod x $ lengthNum x)) &&
  749. (esPolidiv $ div x 10)
  750. {-2. Los numeros expansivos se definen de la siguiente forma:
  751. el primer numero expansivo es el 1
  752. dado un numero expansivo, para calcular el siguiente cada vez que
  753. en el primero aparezcan n cifras consecutivas iguales (p.ej. 3333) se
  754. sustituiran por n seguido de la cifra que se repite (en el ejemplo 43).
  755. Asi, los primeros numeros expansivos son:
  756. 1 -> un uno: 11
  757. 11 -> dos unos: 21
  758. 21 -> un dos, un uno: 1211
  759. 1211 -> un uno, un dos, dos unos: 111221
  760. ...
  761. Se pide programar en HUGS las siguientes funciones:
  762. (a) (15 puntos) Una funcion expand que, dada una lista con las cifras de
  763. un numero expansivo genere el siguiente.-}
  764. {-Examen Febrero 2010
  765. Se pide programar en HUGS las siguientes funciones que puedan dar una
  766. respuesta incluso si una (pero no las dos) de las listas que se les pasa como
  767. parámetros es una lista infinita:
  768. (a) (1 punto) Una función masCortata que, dadas dos listas a y b nos diga
  769. si la lista a es más corta que la lista b.-}
  770. masCorta ::[a]->[b]->Bool
  771. masCorta xs []=False
  772. masCorta [] ys=True
  773. masCorta (_:tx) (_:ty)=masCorta tx ty
  774. {-(b) Utilizando la función anterior, una función masLarga que
  775. dadas dos listas a y b nos diga si la lista a es mas larga que la lista b-}
  776. masLarga ::[a]->[b]->Bool
  777. masLarga a b=masCorta b a
  778. {-(C) Utilizando las dos funciones anteriores, una función igualLongitud
  779. que, dadas dos listas a y b nos diga si ambas listas tienen la
  780. misma longitud.-}
  781. igualLongitud xs ys= (not $ masCorta xs ys) && (not $ masLarga xs ys)
  782. {-d) (1 punto~ ¿Qué permite que estas funciones admitan que una de las
  783. listas sea infinita? Explique que sucedería si los dos argumentos de
  784. estas funciones fuesen listas infinitas.
  785. La evaluacion perezosa. Se quedaria en un bucle infinito
  786. Una agenda puede ser vista como una lista de tuplas (Fecha,Cita) ordenada
  787. de forma Creciente según las fechas, donde, a su vez, una Fecha, puede ser
  788. vista, como una tupla, de tres enteros que indiquen el día, mes y año de la
  789. fecha y una cita como una cadena de caracteres que la describe.
  790. Se pide programar en HUGS las siguientes funciones para gestionar una
  791. agenda:
  792. (am) (1 punto) Una función nuevaCita que dada una fecha, una Cita, y
  793. una agenda, inserte (de manera ordenada) una nueva Cita en nuestra
  794. agenda.-}
  795. type Agenda=[(Fecha,Cita)]
  796. type Fecha=(Int,Int,Int)
  797. type Cita=[Char]
  798. nuevaCita :: Fecha -> Cita -> Agenda -> Agenda
  799. nuevaCita f c []= [(f,c)]
  800. nuevaCita f c ((fh,ch):t)
  801. | f>fh=(fh,ch):(nuevaCita f c t)
  802. | otherwise=(f,c):(fh,ch):t
  803. -- Funcionaria si el orden es (aaaa,mm,dd)
  804. {-b) Una función citas que dadas dos fechas fi y ff y una
  805. agenda devuelva todas las Citas que haya en la agenda, que tengan
  806. lugar entre ambas fechas.-}
  807. citas :: Fecha -> Fecha -> Agenda -> Agenda
  808. citas fi ff a=filter (\(f,c)->f>=fi && f<=ff) a
  809. {-Una matriz bidimensional se puede implementar en HUGS
  810. mediante una lista en la que cada elemento representa una fila
  811. de la matriz en forma de lista de los elementos que contiene.
  812. Se desea una función columna que dada una matriz y un indice
  813. de columna (que se asumirá válido para la matriz),
  814. devuelva una lista con los elementos de la matriz que están en
  815. esa Columna. Esta función deberá ser hecha mediante una lista por Com-
  816. prensión.-}
  817. columna:: (Eq a)=>[[a]] -> Int -> [a]
  818. columna1 mx i=[a|l<-mx,a<-l,a==(l!!i)]
  819. columna mx i=[l!!j|l<-mx,j<-[0..(length l)],j==i]
  820. {-4. En matemáticas. una sucesión alícuota es una sucesión en la que cada
  821. término es la suma de los divisores propios (todos sus divisores salvo él
  822. mismo) del término anterior. Se pide:
  823. (3) (1 punto) Una función siguiente tal que dado un término de una
  824. sucesión alícuota, Calcule el siguiente término de dicha sucesión. Por
  825. ejemplo:
  826. > siguiente 10
  827. 8 (pues los divisores estrictos de 10 son 1, 2 y 5)
  828. > siguiente 6
  829. 6 (pues los divisores estrictos de 6 son 1, 2 y 3)-}
  830. divs1 n=filter (\x->(mod n x)==0) [1..(div n 2)]
  831. sig1 n=sum $ divs1 n
  832. {-b) Una función alícuota tal que dado un número calcule la
  833. sucesión alícuota, que dicho número genera. Si algún término de la
  834. sucesión se repite, la sucesión es cíclica. La función deberá, detectar
  835. este hecho y detener el Cálculo mostrando Como último término el
  836. primer término repetido. Por ejemplo:-}
  837. alicuota n=until (\l->elem (last l) (init l))
  838. (\l->l++[sig1 $ last l]) [n]
  839. {-Examen Febrero 2010-}
  840. type MA = [[Int]]
  841. type LA = [[(Int,Int)]] -- ERROR
  842. ma=[[inf,2,inf],[3,inf,1],[3,0,inf]]::MA
  843. la=[[(1,2)],[(0,3),(2,1)],[(0,3),(1,0)]] :: LA
  844. inf=999999999 :: Int
  845. {-1.a) -}
  846. gradoMA :: MA -> Int -> Int
  847. gradoMA m x=let nodos=m!!x
  848. in length $ filter (< inf) nodos --ERROR CREO
  849. gradoLA :: LA -> Int -> Int
  850. gradoLA l x = length (l!!x)
  851. {-1.b) -}
  852. adyacentesMA :: MA -> Int -> Int -> Bool
  853. adyacentesMA m x y=
  854. let nodos=m!!x
  855. in (nodos!!y)<inf
  856. adyacentesLA :: LA -> Int -> Int -> Bool
  857. adyacentesLA l x y=elem y (map (fst) (l!!y))
  858. {-1.c) -}
  859. listaAdyacentesMA :: MA -> Int -> [Int]
  860. {- listaAdyacentesMA m x=filter (< inf) (m!!x) ERROR -}
  861. listaAdyacentesMA m x=
  862. let ns=m!!x
  863. r (acc,n) x | x<inf =(n:acc,n+1)
  864. | otherwise =(acc,n+1)
  865. in fst $ foldl r ([],0) ns
  866. listaAdyacentesLA :: LA -> Int -> [Int]
  867. listaAdyacentesLA l x=map (fst) $ l!!x
  868. {-1.d) -}
  869. vecinosMA :: MA -> Int -> Int -> [Int]
  870. vecinosMA _ 0 _=[]
  871. vecinosMA m max x=
  872. let ads=listaAdyacentesMA m x
  873. in nub.(filter$(/= x)) $
  874. ads ++ (concatMap (vecinosMA m (max-1)) ads) --ERROR sin concat ni nub
  875. vecinosLA :: LA -> Int -> Int -> [Int]
  876. vecinosLA _ 0 _=[]
  877. vecinosLA m max x=
  878. let ads=listaAdyacentesLA m x
  879. in nub.(filter$(/= x)) $
  880. ads ++ (concatMap (vecinosLA m (max-1)) ads) --ERROR sin concat ni nub
  881. {-1.e) -}
  882. type Camino=[Int]
  883. costeMA :: MA -> Camino -> Int
  884. costeMA m (h:t)=
  885. let iCosteMA _ [] = 0
  886. iCosteMA x (h':t')
  887. | ((m!!x)!!h')==inf = inf
  888. | otherwise=((m!!x)!!h')+iCosteMA h' t'
  889. in iCosteMA h t
  890. costeLA :: LA -> Camino -> Int
  891. costeLA l (h:t)=
  892. let iCosteLA _ []=0
  893. iCosteLA x (h':t')
  894. |null next = inf
  895. |otherwise =(snd $ head next)+iCosteLA h' t'
  896. where next=filter ((== h).fst) $ l!!x
  897. in iCosteLA h t
  898. {-2.-}
  899. replica :: Int -> [a] -> [a]
  900. replica n []=[]
  901. replica n (h:t)=(take n $ repeat h)++(replica n t) {-Error-}
  902. {-3. Se da por supuesto que los si algun nodo es "vacio" es valido-}
  903. monticulo :: Ord a=>[a]->Bool
  904. monticulo []= True
  905. monticulo lst=let imonticulo n
  906. | length lst < n = True
  907. | (comp 1 && comp 2)=imonticulo (n+1)
  908. | otherwise=False
  909. where comp k=(length lst)<=(2*n+k)||
  910. (lst!!(2*n+k))<=lst!!n
  911. in imonticulo 0