COMP712 Tutorial #11: LISP – DO (ans)
1. Using DO, write a function Add-1 which given a list of numbers will return the same list with all the numbers incremented by 1:
(defun add-1 (L)
(do ((L L (cdr L))
(result nil (cons (1+ (car L)) result)))
((null L) result)))
2. Using DO, write a LISP function, except-last, which given a list of lists will return a new list of lists whereby each list has its last element removed. For example:
;; butlast is a pre-defined function in LISP
(defun except-last (L)
(do ((L L (cdr L))
(ans nil (cons (butlast (car L)) ans)))
((null L) (reverse ans))))
3. Write a LISP function, omitsecondlast, which given a list will return a new list without its second last element.
(defun omitsecondlast (L)
(reverse (cons (car (reverse L)) (cddr (reverse L)))))
4. Using Do, write a LISP function, nth-element, which given a number and a list will return the nth element in that list. For example:
(defun nth-element (n L)
(do ((n n (1- n)) (L L (cdr L)))
((zerop n) (car L))))
5. Write a LISP function which given an argument will do the following. If the argument is a number, return a number which is twice its value. If it is a list, return a list containing its first element. Otherwise, return the argument as it is.
(defun fun (L)
(cond ((numberp L) (* 2 L))
((listp L) (list (car L)))
(t L)))
6. Using Do, write a function, pair-list, which given two lists (of equal length), will return a list of paired elements from them. For example:
(defun pair-list (L1 L2)
(do ((L1 L1 (cdr L1))
(L2 L2 (cdr L2))
(ans nil (cons (list (car L1) (car L2)) ans)))
((null L1) (reverse ans))))
Try re-writing the above using do*. Is it better or worse? I hope you realize parallel assignment of variables is very useful.
7. Write a LISP function, switch, which given two lists as arguments will return the first list except its first element is replaced by the last element of the second list. For example:
> (switch ‘(a b c d) ‘(e f g))
(g b c d)
(defun switch (L1 L2) (append (last L2) (cdr L1)))
8. Using Do, write a LISP function, add-up, which given a list of lists of numbers will return a list of lists of the sum of those numbers:
> (add-up ‘((1 2 3) (4 5) (6 7 8 1)))
(6 9 22)
(defun add-up (L)
(do ((L L (cdr L))
(result nil
(cons (apply #’+ (car L)) result)))
((null L) (reverse result))))
9. Write a LISP function, Compute, which given a list of 3 items, forming an arithmetic expression, will return the value of the expression. The operator can be +, -, * or /.
> (compute ‘(4 + 2))
6
> (compute ‘(6 / 3))
2
(Defun compute (L)
(cond ((equal (second L) ‘+) (+ (first L) (third L)))
((equal (second L) ‘-) (- (first L) (third L)))
((equal (second L) ‘*) (* (first L) (third L)))
(t (/ (first L) (third L)))))
or, a smarter solution:
(defun compute (L) (funcall (second L) (first L) (third L)))