MC600 - Segundo semestre de 2003 - LISTA 2 ------------------------------------------ 1. O que estas funções fazem? a. (defun enigma (x) (and (not (null x)) (or (null (car x)) (enigma (cdr x))))) b. (defun mystery (x y) (if (null y) nil (if (eql (car y) x) 0 (let ((z (mystery x (cdr y)))) (and z (+ z 1)))))) 2. O que poderia ser posto no lugar de "x" nas expressões abaixo? a. > (car (x (cdr '(a (b c) d)))) B b. > (x 13 (/ 1 0)) 13 c. > (x #'list 1 nil) (1) a. Resposta: Poderia ser utilizado car, pois: (cdr '(a (b c) d))) daria ((b c) d) (car '((b c) d)) daria (b c) (car '(b c)) daria B. b. Resposta: Poderia ser utilizado "or", pois or avalia as expressões procurando por um verdadeiro, caso contrario retornando nil. Como todo número é avaliado como verdadeiro então só seria avaliado como (or 13), retornando o 13 como valor. Não avalia (/ 1 0) pois já achou um verdadeiro antes. c. Resposta: Poderia ser utilizado "apply", pois apply faria com que fosse chamanda a função list com os parametros 1 e nil, retornando a lista criada como resposta. 3. Usando apenas operadores apresentados em aula, defina uma função que receba uma lista como um argumento e retorne "true" se um dos elementos é uma lista. Solução: (defun temlista( x ) (if (null x) nil (if (listp (car x)) T (temlista( cdr x))))) 4. Dê uma definição iterativa e uma recursiva de uma função que: a. recebe um inteiro positivo e imprima o mesmo número de pontos. b. recebe uma lista e retorna o número de vezes que o símbolo "a" aparece nela. Solução: ;; ;;função recursiva que imprime o número dado (n) ;;de pontos na tela. (defun imprime (n) ;define cabeçalho (format t ".") ;imprime "." (if (> n 1) ;testa se chegou ao fim da recursão (n = 1 é o critério de parada) (imprime (- n 1)) ;chamada recursiva para n-1 ) ; ) ; ;;imp_iter ;; ;;versão não-recursiva (iterativa) da função ;;anterior. (defun imp_iter (n) ;cabeçalho (dotimes (i n) ;laço (repete n vezes) (format t ".") ;imprime "." ) ; ) ; ;;conta ;; ;;função recursiva para contar o número de vezes ;;que o símbolo - a - aparece em lista. (defun conta (lista) ;cabeçalho (if (null lista) ;fim da recursão? (lista nula) 0 ; SIM-> retorna 0; (if (equal 'a (car lista)) ; NÂO-> primeiro elemento é "a"? (+ 1 (conta (cdr lista))) ; SIM-> soma 1 ao montante encontrado (conta (cdr lista)) ; NÃO-> não adiciona nada ao montante ) ; ) ; ) ; ;;conta_iter ;; ;;versão iterativa de "conta" (defun conta_iter (lista) ;cabeçalho (let ((conta 0)) ;conta iniciada com 0 nesse escopo (dolist (el lista) ;laço (percorre lista) (if (equal 'a el) ;elemento da lista é "a"? (incf conta) ; SIM-> soma 1 ao montante encontrado ) ; ) ; conta ;retorna o valor final encontrado ) ; ) ; 5. Um amigo está tentando escrever uma função que retorna a soma de todos os elementos não nulos em uma lista. Ele escreveu duas versões desta função, mas nenhuma delas funciona. Explique o que há de errado com cada uma delas e dê uma versão correta. a. (defun summit (lst) (remove nil lst) (apply #'+ lst)) b. (defun summit (lst) (let ((x (car lst))) (if (null x) (summit (cdr lst)) (+ x (summit (cdr lst)))))) Solução: item a: problema: remover não age na lista lst. correção: abaixo (defun summit (lst) (apply #'+ (remove nil lst)) ) item b: problema: faltou caso de parada quando lista é vazia correção: abaixo (defun summit (lst) (if (null lst) 0 (let ((x (car lst))) (if (null x) (summit (cdr lst)) (+ x (summit (cdr lst))) ) ) ) )