My solutions to "ANSI Common Lisp": Chapter 2
Exercise 1
- The two inner function calls,
(- 5 1)and(+ 3 7), are evaluated. Next, their values are used as arguments to the outer function call, yielding a result of 14. - The inner function
(+ 2 3)is evaluated and passed tolist, which returns the list(1 5). - The predicate
(listp 1)evaluates to nil, so the second expression in theifblock,(+ 3 4), is evaluated to 7. This value is returned by theifblock. list’s arguments are evaluated and their values stored in a list. The first argument evaluates to nil, as(listp 3)is false; the second argument evaluates to 3. Thus, the entire expression evaluates to(nil 3).
Exercise 2
(cons 'a '(b c))(cons 'a (cons 'b '(c)))(cons 'a (cons 'b (cons 'c nil)))
Exercise 3
(defun fourth-element (list) (car (cdr (cdr (cdr list)))))
Exercise 4
(defun greater-of-two (a b) (if (> a b) a b))
Exercise 5
enigmais a function on lists. It returnstfor non-nil lists which contain at least one nil element, and nil on all other lists.mysteryreturns the index of the first occurrence ofxwithin the listy, if it is present within the list, or nil otherwise. Theandfunction is used to prevent(+ z 1)from being evaluated in the case thatzis nil; this statement works as such becauseandreturns the value of its last argument if the whole expression evaluates to a truth value.
Exercise 6
cdrorapply
Exercise 7
(defun contains-list? (list)
(if (null list)
nil
(if (listp (car list))
(car list)
(contains-list? (cdr list)))))
Exercise 8
-
Iterative version:
(defun print-dots-iterative (n) (do ((i 1 (+ i 1))) ((> i n)) (format t ".")) (format t "~%"))Recursive version:
(defun print-dots-recursive (n) (if (> n 0) (progn (format t ".") (print-dots-recursive (- n 1))) (format t "~%"))) -
Iterative version:
(defun count-a-iterative (list) (let ((n 0)) (dolist (ele list n) (if (eql ele 'a) (setf n (+ n 1))))))Recursive version:
(defun count-a-recursive (list) (if list (let ((rest (count-a-recursive (cdr list)))) (if (eql (car list) 'a) (+ rest 1) rest)) 0))
Exercise 9
-
The program would work as written if
removestored the modified list in the original variable. However,removeis a non-destructive function. The original version ofsummitcould be rewritten correctly as follows:(defun summit (lst) (apply #'+ (remove nil lst)))
-
The problem is that this recursive incarnation of
summitdoes not test for the base case which occurs at the end of the list (where the cdr is nil), and so it will recurse until the stack fills up. A corrected version:(defun summit (lst) (let ((x (car lst))) (if (cdr lst) (if (null x) (summit (cdr lst)) (+ x (summit (cdr lst)))) (if (null x) 0 x))))
0 Comments