Licenciatura em Engenharia Informática e Computação
Introdução à Programação I
Ano lectivo de 2001/2002

Exame de Recurso, 8/2/2002

RESOLUÇÃO


1.1

(define distancia-entre-pontos
  (lambda (p1 p2)
    (let ((p1-x (car p1))
          (p1-y (cadr p1))
          (p2-x (car p2))
          (p2-y (cadr p2)))
       (let ((dx (- p2-x p1-x))
            (dy (- p2-y p1-y)))
        (sqrt (+ (* dx dx)
                 (* dy dy)))))))
1.2
(define distancia-percurso
  (lambda (percurso)
    (letrec ((mais-um-passo 
              (lambda (perc x y)
                (if (null? perc)
                    (distancia-entre-pontos (list 0 0) (list x y))
                    (cond ((equal? (car perc) 'n)
                           (mais-um-passo (cdr perc) x (add1 y)))
                          ((equal? (car perc) 's)
                           (mais-um-passo (cdr perc) x (sub1 y)))
                          ((equal? (car perc) 'e)
                           (mais-um-passo (cdr perc) (add1 x) y))
                          ((equal? (car perc) 'o)
                           (mais-um-passo (cdr perc) (sub1 x) y))
                          (else 'percurso-ambiguo))))))
      (mais-um-passo percurso 0 0))))
2.1
(define ver-jornada
  (lambda (jornada)
    (let ((n-equipas (vector-length jornada)))
      (letrec ((aux 
                (lambda (n)
                  (if (< n n-equipas)
                      (let ((equipa (vector-ref jornada n)))
                        (begin 
                          (display "equipa ")(display (car equipa))
                          (display " - ")
                          (display (cadr equipa))
                          (display " ")
                          (display (caddr equipa))
                          (display " | ")
                          (aux (add1 n))))))))
             (aux 0)))))
2.2
(define cria-jornada 
  (lambda (n-equipas)
    (let ((jornada (make-vector n-equipas)))
      (letrec ((aux 
                (lambda (n)
                  (if (< n n-equipas)
                      (begin 
                        (vector-set! jornada n (list (add1 n) -1 -1))
                        (aux (add1 n)))))))
        (aux 0)
        jornada))))
2.3


2.4
(define situacao-equipa-ate
  (lambda (campeonato equipa n-jornada)
    (let ((i-equipa (sub1 equipa))
          (n-jornadas (vector-length campeonato)))
      (letrec ((aux 
                (lambda (n pontos total-marcados total-sofridos)
                  (if (< n n-jornada)
                      (let* ((jornada (vector-ref campeonato n))
                             (equipa (vector-ref jornada i-equipa))
                             (marcados (cadr equipa))
                             (sofridos (caddr equipa)))
                        (cond ((> marcados sofridos)
                               (aux (add1 n) (+ pontos 3) (+ marcados total-marcados) (+ sofridos total-sofridos))) 
                              ((= marcados sofridos)
                               (aux (add1 n) (+ pontos 1) (+ marcados total-marcados) (+ sofridos total-sofridos)))
                              (else
                               (aux (add1 n) pontos (+ marcados total-marcados) (+ sofridos total-sofridos)))))
                      (list pontos total-marcados total-sofridos)))))
        (aux 0 0 0 0)))))
Anexo A
; ---------- pergunta 2 -------------
; sugestoes para melhoria sao bem-vindas.
;
; uma jornada e' um vector, em que cada elemento, um por cada equipa,
; e' uma lista composta por: 
; um numero (a comecar em 1, ...) que representa a equipa;
; dois inteiros que representam, respectivamente, o numero de golos 
; marcados e sofridos pela equipa. 
; Estes inteiros sao, inicialmente, -1 e -1.
; 
; cria um objecto do tipo jornada, em que jogam
; varias equipas, cujo numero e' definido pelo parametro.
(define cria-jornada 
  (lambda (n-equipas)
    (let ((jornada (make-vector n-equipas)))
      (letrec ((aux 
                (lambda (n)
                  (if (< n n-equipas)
                      (begin 
                        (vector-set! jornada n (list (add1 n) -1 -1))
                        (aux (add1 n)))))))
        (aux 0)
        jornada))))
;
; um campeonato e' um vector de objectos do tipo jornada. O numero  de
; elementos do vector e' igual a 2 x (numero de equipas - 1),
; pois, num campeonato, uma equipa joga com todas as outras, 
; uma vez em casa e outra fora.
;
; cria um objecto do tipo campeonato, em que jogam
; varias equipas, cujo numero e' definido pelo parametro.
(define cria-campeonato
  (lambda (n-equipas)
    (let* ((n-jornadas (* 2 (sub1 n-equipas)))
           (campeonato (make-vector n-jornadas)))
      (letrec ((aux 
                (lambda (n)
                  (if (< n n-jornadas)
                      (begin 
                        (vector-set! campeonato n (cria-jornada n-equipas))
                        (aux (add1 n)))))))
        (aux 0)
        campeonato))))
;
; introduz um resultado de um campeonato, referente a uma equipa,
; numa jornada. O resultado e' definido pelo numero de golos
; marcados e sofridos (sem verificar valores dos parametros)
(define resultado!
  (lambda (campeonato equipa jornada marcados sofridos)
    (let* ((i-jornada (sub1 jornada))
           (i-equipa (sub1 equipa))
           (jogos (vector-ref (vector-ref campeonato i-jornada) i-equipa)))
      (set-car! (cdr jogos) marcados)
      (set-car! (cddr jogos) sofridos))))
;
; visualiza os resultados por jornada e por equipa, no formato:
; equipa 1 - 1 2
; equipa 2 - 3 1
; ...
(define ver-jornada
  (lambda (jornada)
    (let ((n-equipas (vector-length jornada)))
      (letrec ((aux 
                (lambda (n)
                  (if (< n n-equipas)
                      (let ((equipa (vector-ref jornada n)))
                        (begin 
                          (display "equipa ")(display (car equipa))
                          (display " - ")
                          (display (cadr equipa))
                          (display " ")
                          (display (caddr equipa))
                          (display " | ")
                          (aux (add1 n))))))))
             (aux 0)))))
;
; visualiza o campeonato, jornada a jornada (os resultados ainda nao 
; preenchidos sao visualizados com o valor inicial: -1 -1), no formato:
; jornada 1: equipa 1 - 2 0 | equipa 2 - 0 2 | ...
; jornada 2: equipa 1 - 3 0 | equipa 2 - 2 2 | ...
; ...
(define ver-campeonato
  (lambda (campeonato)
    (let ((n-jornadas (vector-length campeonato)))
      (letrec ((aux 
                (lambda (n)
                  (if (< n n-jornadas)
                      (begin 
                        (newline)(display "jornada ")(display (add1 n))(display ": ")
                        (ver-jornada (vector-ref campeonato n))
                        (aux (add1 n)))))))
        (aux 0)))))
;
; visualiza os resultados de uma equipa, em todo o campeonato (os 
; resultados ainda nao preenchidos sao visualizados com o valor 
; inicial: -1 -1), no formato:
; equipa 2:
; jornada 1 - 2 3
; jornada 2 - 3 1
;   ...
(define ver-equipa
  (lambda (campeonato equipa)
    (let ((i-equipa (sub1 equipa))
          (n-jornadas (vector-length campeonato)))
      (letrec ((aux 
                (lambda (n)
                  (if (< n n-jornadas)
                      (begin 
                        (newline)(display "jornada ")(display (add1 n))(display " - ")
                        (let* ((jornada (vector-ref campeonato n))
                               (equipa (vector-ref jornada i-equipa)))
                          (begin 
                            (display (cadr equipa))
                            (display " ")
                            (display (caddr equipa))
                            (aux (add1 n)))))))))
        (display "equipa ")(display equipa)(display ":")
        (aux 0)))))
; 
; calcula a situacao referente a uma equipa (a-equipa), desde a 
; primeira jornada ate' 'a jornada (n-jornada) de um dado campeonato;
; considera 3 pontos em caso de vitoria, 1 em caso de empate;
; devolve uma lista com: o numero de pontos, os golos marcados e 
; os golos sofridos
; nao verifica se os resultados da jornada ja' foram introduzidos
(define situacao-equipa-ate
  (lambda (campeonato a-equipa n-jornada)
    (let ((i-equipa (sub1 a-equipa))
          (n-jornadas (vector-length campeonato)))
      (letrec ((aux 
                (lambda (n pontos total-marcados total-sofridos)
                  (if (< n n-jornada)
                      (let* ((jornada (vector-ref campeonato n))
                             (equipa (vector-ref jornada i-equipa))
                             (marcados (cadr equipa))
                             (sofridos (caddr equipa)))
                        (cond ((> marcados sofridos)
                               (aux (add1 n) (+ pontos 3) (+ marcados total-marcados) (+ sofridos total-sofridos))) 
                              ((= marcados sofridos)
                               (aux (add1 n) (+ pontos 1) (+ marcados total-marcados) (+ sofridos total-sofridos)))
                              (else
                               (aux (add1 n) pontos (+ marcados total-marcados) (+ sofridos total-sofridos)))))
                      (list pontos total-marcados total-sofridos)))))
        (aux 0 0 0 0)))))
;
(define liga (cria-campeonato 4))
; jornada 1
(resultado! liga 1 1 2 0)
(resultado! liga 2 1 0 2)
(resultado! liga 3 1 1 1)
(resultado! liga 4 1 1 1)
; jornada 2
(resultado! liga 1 2 3 0)
(resultado! liga 2 2 2 2)
(resultado! liga 3 2 0 3)
(resultado! liga 4 2 2 2)
;jornada 3
(resultado! liga 1 3 4 0)
(resultado! liga 2 3 1 0)
(resultado! liga 3 3 0 1)
(resultado! liga 4 3 0 4)
(ver-campeonato liga)
(newline)
(ver-equipa liga 1)
(newline)
(situacao-equipa-ate liga 1 3)