Algoritmos y Estructuras de Datos I – Departamento de Computación – Facultad de Ciencias Exactas y naturales – Universidad de Buenos Aires Ejercicios para entrenarse para el coloquio/final de Algoritmos I Diciembre 2009 Ejercicio 1 Indicar verdadero o falso: 1. Si un programa es correcto respecto de una especificación entonces pasa todos los casos de testeo para valores que satisfacen la precondición. 2. Si dos programas que reciben un argumento de entrada, ambos satisfacen la misma especificación, entonces para cada posible valor de entrada ambos programas dan el mismo valor. Ejercicio 2 Sea (P,Q) la especificación de un problema, donde P es la precondición y Q es la postcondición. Sea un programa foo correcto respecto de (P.Q). Indicar verdadero o falso y justificar: 1. foo es correcto respecto de (PvR, Q) 2. foo es correcto respecto de (P, Q^ S) 3. foo es correcto respecto de (P, Q v S) 4. foo es correcto respecto de (P, P) 5. foo es correcto respecto de (Q,P) 6. foo es correcto respecto de (Q,Q) Ejercicio 3 ¿Qué es un tipo de datos? Dar un ejemplo de un tipo de datos abstracto y uno de un tipo de datos algebraico. Ejercicio 4 Proponer un conjunto de valores y dar un ejemplo de un tipo algebraico de datos que sea adecuado para representarlo. Dar otro ejemplo de tipo algebraico de datos que sea inadecuado para representar al mismo conjunto de valores. En ambos casos justificar. Ejercicio 5 Indicar las similitudes y diferencias del tipo de datos lista y del tipo de datos arreglo vistos como tipos abstractos de datos (primitivos). Dar sus observadores y sus invariantes de tipos. Ejercicio 6 Dar un ejemplo de un programa imperativo donde no se viole la transparencia referencial. Justificar. Ejercicio 7 Definir en Haskell un tipo de datos que represente un árbol binario de números enteros, que tenga un número entero en cada nodo y en cada hoja. Dar la función en Haskell que recorre un árbol de éstos en inorden, y produce la lista de los nodos visitados. Ejercicio 8 El algoritmo de la búsqueda binaria se puede extender al de búsqueda ternaria, donde en cada iteración el arreglo se divide en tres partes y se selecciona el tercio de búsqueda apropiado. Especificar el problema de búsqueda ternaria y programarlo en lenguaje imperativo. Dar el invariante del ciclo. Ejercicio 9 1. Enunciar el teorema del invariante. 2. Dar un ejemplo donde se cumple y otro ejemplo donde no. 3. Enunciar el teorema del invariante con la siguiente modificación: consignar que la función variante sea creciente en cada iteración del ciclo. Ejercicio 10 Sea C un predicado con la siguiente propiedad: hay un primer número natural n0 > 1 que cumple C y todos los naturales mayores que n0 también cumplen C. Dar un algoritmo que resuelva el problema de encontrar n0 y que sea más rápido más rápido que el de la simple búsqueda lineal. El algoritmo debe aprovechar la propiedad de la condición C, y en vez de visitar los naturales secuencialmente, visita solamente algunos, dando saltos exponencialmente grandes. Ejercicio 11 Dar una función en Haskell que resuelva el siguiente problema. problema lcp(a: [[Char]])= res: [Z]{ requiere long(a)>= 1 asegura res=[longitud_prefijo_comun(a[i],a[i+1]) | i<- [0..long(a)-2]] aux longitud_prefijo_comun(s, t)= max[i +1 | i<- [0.. min[long(s), long(t)]], s[0..i]== t[0..i] ] } donde max y min son las funciones que seleccionan, respectivamente, los valores máximos y mínimos de una lista de enteros. Ejercicio 12 Dar la postcondición Q para la cual la siguiente función f es correcta. problema f(n:Z) = res:[[Char]] { requiere n >= 0; asegura Q: ...; } f :: Int ­> [[Char]] f 0 = [] f 1 = [“0”, “1”] f n | n > 0 = h '0' (f (n ­ 1)) ++ h '1' (f (n ­ 1)) h :: Char ­> [[Char]] ­> [[Char]] h x [] = [] h x (y : ys) = (x : y) : h x ys Ejercicio 13 Dado el siguiente problema: problema bblog(x:Z)= res:Z{ requiere x>=1 asegura res=[log2 x] } donde [ ] denota la parte entera, y log2 denota el logaritmo en base 2. 1. Utilizar el algoritmo de búsqueda binaria para resolver el problema bblog. Describir (dar el pseudocódigo) la función para ser programada en imperativo y codificarla. 2. Dar la especificación del ciclo utilizado (Precondición y Postcondición del ciclo, Invariante, guarda, función variante y cota). Ejercicio 14 ¿Qué es una variable en lenguaje imperativo? Explicar la operación de asignación, y dar su semántica usando la noción de estado, y transformación de estados. ¿cómo difieren las variables en imperativo de las variables en funcional? Ejercicio 15 Dado un programa imperativo ¿Cada vez que se ejecuta con los mismos argumentos de entrada, realiza la misma transformación de estados? Ejercicio 16 El paradigma de programación imperativa permite pasar argumentos por copia y por referencia. Dar dos razones por las cuales al programar una función conviene elegir el pasaje por referencia. Ejercicio 17 Dar tres razones por las cuales una función recursiva se puede indefinir. Ejercicio 18 ¿A qué se llama órdenes de evaluación en el paradigma de la programación funcional? Describir pros y los contras de cada uno. Ejercicio 19 Dado el siguiente programa en C++. void bbs(int a[], int n){ listo=false; while (!listo){ listo=swap_consecutivos(a,n); } bool swap_consecutivos(int a[], int n){ int sin_cambios=true; int i=0; while (i<= n – 2){ if (a[i] > a[i+1]){ swap(a[i], a[i+1]); sin_cambios=false; } i++; } return sin_cambios; } Se pide: 1. Hacer el seguimiento de los estados por los que pasa la ejecución de bbs([8,1,4,2,5], 5) . 2. Dar una expresión variante decreciente y acotada del ciclo de la función bbs. (ayuda: Dar la postcondicion de swap_consecutivos, y observar que en cada iteración el arreglo a[ ] pasa a tener un segmento final definitivo de tamaño mayor que el del paso anterior. 3. Especificar un problema para el cual la función bbs sea correcta. Ejercicio 20 Sea el siguiente programa en C++. int p(){ int x=2; while (x>=0){ if (x mod 2==0) { else { } return x; x= 2x+1}; x=x-1 }; } 1. Sea la siguiente expresión variante demostrar terminación? 2. ¿Este programa termina? v=1/2x, si x es par; v=1/x si x es impar ¿Por qué no sirve para