Prova Final de Linguagens de Programação - DCC024B - Ciência da Computação Nome: Eu dou minha palavra de honra que não trapacearei neste exame. Número de matrícula: As regras do jogo: A prova é sem consulta. Quando terminar, não entregue nada além do caderno de provas para o instrutor. Quando escrever código, a sintaxe correta é importante. Cada estudante tem direito a fazer uma pergunta ao instrutor durante a prova. Traga o caderno de provas quando vier à mesa do instrutor. A prova termina uma hora e quarenta minutos após seu início. Seja honesto e lembre-se: você deu sua palavra de honra. Alguns conselhos: Escreva sempre algo nas questões, a fim de ganhar algum crédito parcial. Se não entender a questão, e já tiver gasto sua pergunta, escreva a sua interpretação da questão junto à resposta. A prova não é difícil, ela é divertida, então aproveite! Tabela 1: Pontos acumulados (para uso do instrutor) Questão 1 Questão 2 Questão 3 Questão 4 Questão 5 Questão 6 1
1. Exceções podem ser usadas para modificar o fluxo de controle do programa, sem que situações de erro tenham sido produzidas. Por exemplo, imagine que um programa faça uma busca em um grafo direcionado, procurando por nós sem saída. Um nó sem saída é um elemento de um grafo direcionado que não possui arestas de saída. O grafo direcionado na parte (a) da figura abaixo possui dois nós sem saída, D e F. (a) (b) public class Node { (c) A private String nodename; C B public boolean isvisited; private List<Node> children;... public void searchfordeadend() { isvisited = true; if (children.size() == 0) reportdeadend(); else { for (Node n : children) { if (!n.isvisited) D n.searchfordeadend(); F E... public void reporddeadend() { G (ii) void searchgraph(node n) { try { n.searchfordeadend(); catch (DeadEndException dee) { Node node = dee.getnode(); String nodename = node.getname(); System.out.println("Sem saida" + nodename); public class DeadEndException extends (i) { (iii) A função reportdeadend() na classe Node (Figura (b) acima) interrompe uma busca em grafo, e dispara uma exceção para o código chamador, caso um nó sem saída tenha sido encontrado. (a) (3 Pontos) A classe DeadEndException é uma exceção verificada estaticamente ou não? Justifique a sua resposta com base na declaração do método rerpotdeadend() e da classe DeadEndException. (b) (1 Pontos) Dada a sua resposta para a questão anterior, quais dentre as classes Error, Exception e RuntimeException podem substituir o item (i) na figura acima? (c) (3 Pontos) Implemente o corpo do método reportdeadend(). Em outras palavras, escreva o código que deve ficar no item (ii) da figura. (d) (3 Pontos) Implemente o corpo da classe DeadEndException (item iii acima). Sua implementação deve possuir um construtor, e atributos da classe. Construtor é o método usado para instanciar objetos da classe, e atributos são os campos usados para armazenar os dados que constituem um objeto. 2
2. Esta questão refere-se ao programa abaixo. A classe MyList cria uma cópia de uma lista. class MyList: def init (self, list): self.list = [] for x in list: self.list.insert(0, x) def invert(self):... def str (self): return str(self.list) (a) (6 Pontos) o método invert inverte a lista armazenada em uma instância de MyList. Por exemplo: >>> o = MyList([1,2,3]) >>> print o [3, 2, 1] >>> o.invert() >>> print o [1, 2, 3] Implemente esse método. (b) (4 Pontos) Assuma que a única forma de inserirmos elementos em uma lista fosse via o método insert, usado como a seguir: >>> l = [1, 2, 3] >>> l.insert(0, "a") >>> l [ a, 1, 2, 3] >>> l.insert(2, "b") >>> l [ a, 1, b, 2, 3] Assuma também que uma vez criada a lista, não houvesse qualquer forma de remover algum de seus elementos. Discuta pelo menos uma forma de criar uma lista imutável em python, dada essas duas suposições. Uma lista imutável não pode receber, nem perder elementos, uma vez criada. 3
3. (10 Pontos) Um Quadrado Mágico de lado N é uma matriz de N N posições. Cada célula dessa matriz contém um número inteiro. Todos os números inteiros presentes na matriz são diferentes. A soma de cada linha, coluna, ou diagonal do quadrado mágico é sempre igual. Neste exercício, você deve implementar um predicado em Prolog que construa um quadrado mágico de lado 3, com os números {1, 2, 3, 4, 5, 6, 7, 8, 9. Um exemplo de solução é mostrado logo abaixo: 2 7 6 9 5 1 4 3 8 Seu predicado deve chamar-se magic(x11, X12, X13, X21, X22, X23, X31, X32, X33), sendo cada X ij um elemento da matriz resposta, conforme mostra o desenho abaixo: X 11 X 12 X 13 X 21 X 22 X 23 X 31 X 32 X 33 magic(x11, X12, X13, X21, X22, X23, X31, X32, X33). X11 = 2, X12 = 7, X13 = 6, X21 = 9, X22 = 5, X23 = 1, X31 = 4, X32 = 3, X33 = 8. A fim de tornar a sua tarefa mais simples, sinta-se livre para usar os predicados sum e perm, definidos logo abaixo: sum([], 0). sum([h T], S) :- sum(t, S1), S is H + S1. perm([], []). perm(t, L) :- member(h, T), select(h, T, L1), perm(l1, L2), L = [H L2]. 4
4. Esta questão refere-se à função abaixo, implementada em SML, que calcula o n-ésimo termo da sequência de Fibonacci: fun fib 0 = 1 fib 1 = 1 fib n = fib (n - 1) + fib (n - 2) (a) (2 Pontos) Qual o tipo inferido para essa função? (b) (3 Pontos) Essa função possui complexidade super-linear. Em outras palavras, ela é mais lenta que O(N), onde N seria o tamanho do parâmetro de entrada n. Qual é a complexidade assimptótica dessa função? Justifique a sua resposta. Não é necessário uma prova formal de complexidade. (c) (5 Pontos) Re-escreva a função fib para que ela tenha de fato complexidade linear. A sua nova função, que deverá ser chamada fastfib, precisa ter a mesma assinatura de tipos que a função fib original. Contudo, sinta-se livre para declarar dentro do escopo de fastfib quantas funções e variáveis auxiliares você julgar necessárias. 5
5. Essa questão diz respeito ao mecanismo de coleta de lixo conhecido como contagem de referência. Um coletor de lixo por contagem de referências associa um contador a cada posição de memória que pode ser referenciada por ponteiros. Sempre que uma nova referência é criada, o contador é incrementado. Se um ponteiro deixa de existir, por que sai de escopo, ou porque é eliminado explicitamente pelo usuário, então o contador é decrementado. O código abaixo, em pseudo-c, ilustra essa técnica: void foo(int* x) { int* a = x; // incrementa contador de x int* b = a; // incrementa contador de x int* y = malloc(8); // cria nova localidade, com contador == 1 return; // decrementa duas vezes o contador de x, e uma vez o de y; (a) (3 Pontos) Coletores por contagem de referência sofrem de um problema sério: as referências cíclicas. Explique que problema é esse, e ilustre sua explicação com um exemplo de programa. (b) (4 Pontos) O problema das referências cíclicas não existe no sub-conjunto de SML que foi visto em sala. Por quê? (c) (3 Pontos) Coletores por contagem de referências são adequados para sistemas de tempo real. Em particular, eles são melhores que coletores mais modernos, como as técnicas de marcação e varredura e cópia e coleta para esse tipo de sistema. Por que coletores por contagem de referência são bons para sistemas de tempo real? 6
6. Este exercício refere-se aos mecanismos de passagem de parâmetros adotados em SML/NJ. As duas questões abaixo devem ser respondidas: (a) (5 Pontos) Linguagens de programação que usam os seguintes mecanismos de passagem de parâmetro: necessidade nome expansão de macro são chamadas linguagens estritas. O que são linguagens estritas? Em outras palavras, o que os três mecanismos de passagem de parâmetros acima têm em comum? (b) (5 Pontos) Escreva um programa que demostre que SML é uma linguagem estrita. (c) (1 Ponto Extra) Cite cinco das sete maravilhas do mundo clássico. 7