Instituto de Computación - Facultad de Ingenierı́a Programación 2 - Curso 2014 Solución Examen de Programación 2 23 de febrero de 2015 Ejercicio 1 PROCEDURE InsOrd (L : LNat; x : CARDINAL) : LNat; VAR nodo, Lres : LNat; BEGIN Lres := NIL; (* Copio los elementos de L mayores que a x *) WHILE (L <> NIL) AND (L^.elem > x) DO NEW(nodo); nodo^.elem := L^.elem; nodo^.sig := Lres; Lres := nodo; L := L^.sig; END; (* Inserto x *) NEW(nodo); nodo^.elem := x; nodo^.sig := Lres; Lres := nodo; (* Copio los elementos de L menores o iguales a x *) WHILE (L <> NIL) DO NEW(nodo); nodo^.elem := L^.elem; nodo^.sig := Lres; Lres := nodo; L := L^.sig; END; RETURN Lres; END InsOrd; Página 1 de 6 Instituto de Computación - Facultad de Ingenierı́a Programación 2 - Curso 2014 Ejercicio 2 a) En primer lugar definamos la especificación: DEFINITION MODULE ColaPrioridadExt; TYPE ColaPrioridadExt; (** Constructoras **) PROCEDURE EmptyCP (): ColaPrioridadExt; (* Devuelve la cola de prioridad vacı́a *) (* PRECONDICIONES: no tiene *) PROCEDURE InsertCP (elem: T; p: CARDINAL; cp: ColaPrioridadExt): ColaPrioridadExt; (* Inserta el elemento elem con prioridad p en la cola de prioridad cp *) (* PRECONDICIONES: no tiene *) (** Predicados **) PROCEDURE IsEmptyCP (cp: ColaPrioridadExt): BOOLEAN; (* Devuelve TRUE si la cola de prioridad cp es vacı́a *) (* PRECONDICIONES: no tiene *) (** Selectoras **) PROCEDURE FindMin (cp: ColaPrioridadExt): T; (* Devuelve el elemento con prioridad mı́nima de la cola de prioridad cp *) (* PRECONDICIONES: NOT IsEmptyCP(cp) *) (** Destructoras **) PROCEDURE DeleteMin (cp: ColaPrioridadExt): ColaPrioridadExt; (* Devuelve la cola de prioridad pasada por parámetro sin el elemento de *) (* menor prioridad *) (* PRECONDICIONES: NOT IsEmptyCP(cp) *) (** Operación nueva **) PROCEDURE BorrarPorPrio (cpe: ColaPrioridadExt; p: CARDINAL): ColaPrioridadExt; (* PRECONDICIONES: no tiene *) END ColaPrioridadExt; A continuación pasamos a la implementación: IMPLEMENTATION MODULE ColaPrioridadExt; TYPE ColaPrioridadExt = ARRAY [1..P] OF Cpe; Cpe = POINTER TO EntradasColaPrio; EntradasColaPrio = RECORD elm : T; sig : Cpe; END; Página 2 de 6 Instituto de Computación - Facultad de Ingenierı́a Programación 2 - Curso 2014 (** Constructoras **) PROCEDURE EmptyCP (): ColaPrioridadExt; VAR aux : ColaPrioridadExt; i : INTEGER; BEGIN FOR i := 1 TO P DO aux[i] := NIL; END; RETURN aux; END EmptyCP; PROCEDURE InsertCP (elem: T; p: CARDINAL; cp: ColaPrioridadExt): ColaPrioridadExt; VAR aux : Cpe; BEGIN NEW(aux); aux^.elm := elem; aux^.sig := cp[p]; cp[p] := aux; RETURN cp; END InsertCP; (** Predicados **) PROCEDURE IsEmptyCP (cp: ColaPrioridadExt): BOOLEAN; VAR res : BOOLEAN; i : INTEGER; BEGIN res := TRUE; i := 0; WHILE (res AND i < P) DO i := i + 1; res := res AND (cp[i] = NIL); END; RETURN res; END IsEmptyCP; (** Selectoras **) PROCEDURE FindMin (cp: ColaPrioridadExt): T; VAR res : BOOLEAN; i : INTEGER; BEGIN res := TRUE; i := 0; WHILE (res AND i < P) DO i := i + 1; res := cp[i] = NIL; END; Página 3 de 6 Instituto de Computación - Facultad de Ingenierı́a Programación 2 - Curso 2014 RETURN cp[i]^.elm; END FindMin; (** Destructoras **) PROCEDURE DeleteMin (cp: ColaPrioridadExt): ColaPrioridadExt; VAR res : BOOLEAN; i : INTEGER; aux : Cpe; BEGIN res := TRUE; i := 0; WHILE (res AND i < P) DO i := i + 1; res := cp[i] = NIL; END; aux := cp[i]; cp[i] := cp[i]^.sig; DISPOSE(aux); RETURN cp; END DeleteMin; (** Operación nueva **) PROCEDURE BorrarPorPrio (cpe: ColaPrioridadExt; p: CARDINAL): ColaPrioridadExt; VAR aux, disp : Cpe; BEGIN aux := cpe[p]; cpe[p] := NIL; WHILE (NOT aux = NIL) DO disp := aux; aux := aux^.sig; DISPOSE(disp); END; RETURN cpe; END BorrarPorPrio; END ColaPrioridadExt; b) Se describirá el orden de las operaciones clásicas de Cola de Prioridad ya que por letra se pedı́a que BorrarPorPrio tuviera O(x), con x la cantidad de elementos con prioridad p. EmptyCP La operación es de O(P ) debido a que se debe asignar el valor NIL para cada prioridad. InsertCP Dado que solo interviene una operación de asignación es de O(1). Página 4 de 6 Instituto de Computación - Facultad de Ingenierı́a Programación 2 - Curso 2014 IsEmptyCP En este caso debemos analizar cual es el peor caso. El mismo se da cuando la cola de prioridad está vacı́a, por lo que se debe verificar P veces si el puntero está en NIL. Entonces la función es O(P ). FindMin Al igual que en el caso anterior debemos analizar cuando se da el peor caso. Como tenemos por precondición que la cola no es vacı́a el peor caso se da cuando debemos recorrer todo el arreglo para buscar el mı́nimo. Entonces la función es de O(P ). DeleteMin Como solo se borra un elemento con mı́nima prioridad, lo único que cuenta para calcular el orden de esta función es la búsqueda de la prioridad mı́nima. Por lo tanto el orden de esta función es O(P ) también. Página 5 de 6 Instituto de Computación - Facultad de Ingenierı́a Programación 2 - Curso 2014 Ejercicio 3 a) PROCEDURE Dif (A, B : ConjCoord) : ConjCoord; VAR res, iterador: ConjCoord; BEGIN res := Vacio(); iterador := A; WHILE NOT EsVacio(iterador) DO IF NOT Pertenece(iterador^.c, B) THEN res := Insertar(iterador^.c, res); END; Iterador := iterador^.sig; END; RETURN res; END Dif; b) PROCEDURE CoordenadasInternas(C1, C2 : Coord; Conj : ConjCoord): ConjCoord; VAR i, incremento, difX, difY: INTEGER; res1, res2: ConjCoord; BEGIN (* Se calcula la diferencia entre las coordenadas para cada eje *) difX := CoordX(C2) - CoordX(C1); difY := CoordY(C2) - CoordY(C1); (* Se calcula en res1 el conjunto de coordenadas con X dentro del rango *) incremento := difX / ABS(difX); i := CoordX(C1); res1 := Vacio(); REPEAT res1 := Union(res1, SubconjX(i, Conj)); i := i + incremento; UNTIL i = CoordX(C2); res1 := Union(res1, SubconjX(CoordX(C2), Conj)); (* Se calcula en res2 el subconjunto de res1 con Y dentro del rango *) incremento := difY / ABS(difY); i := CoordY(C1); res2 := Vacio(); REPEAT res2 := Union(res2, SubconjY(i, res1)); i := i + incremento; UNTIL i = CoordY(C2); res2 := Union(res1, SubconjY(CoordY(C2), res1)); RETURN res2; END CoordenadasInternas; Página 6 de 6