MC600 - Segundo semestre de 2003 - LISTA 4
------------------------------------------


Defina funções LISP que resolvam os seguintes problemas. Para muitos 
deles já existem funções pré-definidas que fazem o serviço. Neste 
caso, o nome da função pré-definida é dado entre parêntesis.


1. Calcule o quadrado de n somando números ímpares.

Resposta:

(defun my-sq (n)
  (if (equal n 0)
      0
      (+ (- (* n 2) 1)
         (my-sq (- n 1))
      )
  )
)


2. Retorne uma lista com o último elemento de uma lista dada (last).

Resposta:

(defun last (lst)
  (if (null lst)
    nil
    (if (null (cdr lst))
      lst
      (last (cdr lst))
    )
  )
)


3. Receba um número variável de parâmetros (um ou mais) e construa uma
   lista com todos eles (list).

Resposta:

(defun mylist (x &rest y)
   (cons x y)
)

Se fosse para receber zero ou mais parâmetros:

(defun mylist (&rest x)
   x
)

   
4. Retorna a concatenação de duas listas dadas como parâmetros (append).

Resposta:

(defun myappend (lst1 lst2)
      (if (null lst1)
          lst2
          (cons (car lst1) (myappend (cdr lst1) lst2))
      )
)


5. Retorna o reverso de uma lista (reverse).

(defun reverse (lista)
  (rev-app lista nil))

;;; rec-app(l1,l2): concatena o reverso de l1 em l2

(defun rev-app (l1 l2)
  (if (null l1)
      l2
      (rev-app (cdr l1) (cons (car l1) l2))
  )
)


6. Verifique se uma lista é sublista da outra, isto é, consiste de um
   trecho consecutivo da outra.

;;; Se não obrigarmos uma sublista a ser um trecho consecutivo:

(defun sublistp (sublst lst)
  (if (null sublst)
    t
    (if (null lst)
      nil
      (if (eq (car sublst) (car lst))
        (sublistp (cdr sublst) (cdr lst))
        (sublistp sublst (cdr lst))
      )
    )
  )
)

;; Se considerarmos que uma sublista deve ser um trecho consecutivo:
 
(defun sublistp( s l )
   (if (prefixo s l)
      T
      (if (null l)
         nil
         (sublistp s (cdr l))
       )
    )
 ) 
 
(defun prefixo (s l)
   (if (null s)
       T
       (if (null l)
          nil
          (if (eql (car s) (car l))
             (prefixo (cdr s) (cdr l))
              nil
           )
        )
    )
 )
 

7. Retorne a sublista contendo os n-1 primeiros elementos de uma lista
   dada de comprimento n (butlast = "todos menos o último").

Resposta:

  (defun menosult (lst)
    (if (null lst)
      nil
      (let ((resto (cdr lst)))
        (if (null resto)
          nil
          (cons (car lst) (menosult resto))
        )
      )
    )
  )