Faculdade de Engenharia da Universidade do Porto
Licenciatura em Engenharia Informática e Computação
Introdução à Programação I
2000/2001

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))))


[Página da disciplina] [J. Lopes Home page]
João Correia Lopes (jlopes AT fe.up.pt).
Last modified: Wed Feb 7 20:11:14 2001