Solutions to Chapter 2 exercises, ANSI Common Lisp (2nd Edition)

Problem 1

;; (+ (- 5 1) (+ 3 7)) => (+ 4 (+ 3 7)) => (+ 4 10) => 14

;; (list 1 (+ 2 3)) => (list 1 5) => (1 5)

;; (if (listp 1) (+ 1 2) (+ 3 4)) => (if nil (+ 1 2) (+ 3 4)) => (+ 3 4) => 7

;; (list (and (listp 3) t) (+ 1 2)) => (list (and nil t) (+ 1 2)) => (list nil (+ 1 2))
;; => (list nil 3) => (nil 3)

Problem 2

;; Expression 1

(cons 'a (cons 'b (cons 'c nil)))

;; Expression 2

(cons 'a '(b c))

;; Expression 3

(cons 'a (cons 'b '(c)))

Problem 3

(defun my-fourth (lst)
  (car (cdr (cdr (cdr lst)))))

(defun my-fourth% (lst)
  (cadddr lst))

Problem 4

(defun greater-of-two (x y)
  (if (> x y)
      x
      y))

Problem 5

;; enigma checks if a non-empty list contains at least one ‘nil’ element.

;; mystery returns the zero-based index of the first parameter in the second parameter (which is a
;; list) otherwise nil.

Problem 6

;; car
;; or
;; apply (funcall would return (1 nil))

Problem 7

(defun any-element-is-list (lst)
  (if (null lst)
      nil
      (or (listp (car lst)) (any-element-is-list (cdr lst)))))

(defun any-element-is-list% (lst)
  (let ((res nil))
    (dolist (obj lst)
      (setf res (or res (listp obj))))
    res))

Problem 8

(defun print-dots-recursive (n)
  (if (= n 0)
      (format t "~%")
      (progn
        (format t ".")
        (print-dots-recursive (- n 1)))))

(defun print-dots-iterative (n)
  (do
   ((i 0 (+ i 1)))
   ((= i n) (format t "~%"))
    (format t ".")))


(defun count-a-recursive (lst)
  (if (null lst)
      0
      (if (eql 'a (car lst))
          (+ 1 (count-a (cdr lst)))
          (count-a (cdr lst)))))

(defun count-a-iterative (lst)
  (let ((count 0))
    (dolist (obj lst)
      (if (eql 'a obj)
          (setf count (+ 1 count))))
    count))

Problem 9

;; The problem with the iterative summit is that the “remove” function returns a new list with
;; the specified element removed, but does not touch the original list (no side-effects).

(defun summit (lst)
  (setf lst (remove nil lst))
  (apply #'+ lst))

;; The problem with the recursive version of summit is that there is no stopping condition! This
;; means that summit keeps looping forever even after the list has become empty.

(defun summit (lst)
  (if (null lst)
      0
      (let ((x (car lst)))
        (if (null x)
            (summit (cdr lst))
            (+ x (summit (cdr lst)))))))

;; cleaner version

(defun summit (lst)
  (if (null lst)
      0
      (if (null (car lst))
          (summit (cdr lst))
          (+ (car lst) (summit (cdr lst))))))
Solutions to Chapter 2 exercises, ANSI Common Lisp (2nd Edition)