Resolução da 1ª chamada, 12/1/2001
1.
(define ackermann (lambda (m n) (cond ((= 0 n) 0) ((= 0 m) (* 2 n)) ((= n 1) 2) (else (ackermann (sub1 m) (ackermann m (sub1 n))))))) ; (define ackermann-geral (lambda (m n) (if (or (negative? m) (negative? n)) -1 (ackermann m n))))2.
(define faz-rectangulo (lambda (xmin xmax ymin ymax) (list xmin xmax ymin ymax))) ;
(define interseccao-rect (lambda (r1 r2) (let ((x1min (car r1)) (x1max (cadr r1)) (y1min (caddr r1)) (y1max (cadddr r1)) (x2min (car r2)) (x2max (cadr r2)) (y2min (caddr r2)) (y2max (cadddr r2))) (let ((x3min (max x1min x2min)) (x3max (min x1max x2max)) (y3min (max y1min y2min)) (y3max (min y1max y2max))) (if (or (< x3max x3min) (< y3max y3min)) 0 (faz-rectangulo x3min x3max y3min y3max))))))3.
3.1 Nome do procedimento: adivinhar Parâmetro: n-perg Inteiro que define o número de perguntas que o programa vai fazer. Objectivo: Lança o programa que, através de um certo número de perguntas e respectivas respostas, irá calcular e visualizar o número pensado pelo utilizador. Nome do procedimento: frase-inicial Parâmetro: n-per Inteiro que define o número de perguntas que irão ser feitas ao utilizador. Objectivo: Visualiza a frase inicial "Pense num numero entre ... " Nome do procedimento: perguntar-todas Parâmetro: n-per Inteiro que define o número de perguntas que irão ser feitas ao utilizador. Objectivo: Faz um número de perguntas definidas pelo seu parâmetro n-per e devolve uma lista com as respostas dadas pelo utilizador. Nome do procedimento: calcula-numero Parâmetro: resp Lista de símbolos (n - não e s - sim) com as respostas dadas pelo utilizador. Objectivo: Calcula e devolve o número correspondente ao conteúdo do parâmetro resp. ; corpo principal - resposta à alínea 3.2 (define adivinhar (lambda (n-perg) (frase-inicial n-perg) (let ((respostas (perguntar-todas n-perg))) (newline) (display "O numero pensado foi: ") ; faz parte da resposta à alínea 3.3 (display (calcular-numero respostas))))) ; faz parte da resposta à alín. 3.3
(define frase-inicial (lambda (n-per) (newline) (display "Pense num numero entre 0 e ") (display (sub1 (expt 2 n-per))) (display "!") (newline) (newline))) ; não pedido (define perguntar-todas (lambda (n-per) (letrec ((num-max (sub1 (expt 2 n-per))) ; (ciclo (lambda (n-p) (if (> n-p n-per) '() (begin (cons (visu-pergunta num-max n-p) (ciclo (add1 n-p)))))))) (ciclo 1)))) ; não pedido (define visu-pergunta (lambda (n-max n-p) (letrec ((ler-ate-s-ou-n (lambda () (display "P") (display n-p) (display "- O numero pensado esta' no conjunto? ") (let ((simb-lido (read))) (if (or (equal? simb-lido 's) (equal? simb-lido 'n)) simb-lido (begin (newline) (ler-ate-s-ou-n))))))) (visu-numeros n-max n-p) ; no final faz newline (ler-ate-s-ou-n)))) ; não pedido (define visu-numeros (lambda (n-max np) (letrec ((ciclo (lambda (numero conta-na-linha) (if (> conta-na-linha 16) (begin (newline) (ciclo numero 0)) (cond ((> numero n-max) (newline)) ((tem-bit-a-1 numero (sub1 np)) (display numero) (display " ") (ciclo (add1 numero) (add1 conta-na-linha))) (else (ciclo (add1 numero) conta-na-linha))))))) (ciclo 1 1)))) ; não pedido (define tem-bit-a-1 (lambda (numero ordem-do-bit) (odd? (quotient numero (expt 2 ordem-do-bit)))))
; faz parte da resposta à alínea 3.3 (define calcular-numero (lambda (resp) (letrec ((valor-resposta (lambda (r p) (if (equal? r 's) p 0))) (ciclo (lambda (res peso) (if (null? res) 0 (+ (valor-resposta (car res) peso) (ciclo (cdr res) (* peso 2))))))) (ciclo resp 1))))