;;; ;;; solution2.lisp: Solution for selected exercises in LISP tutorial 2 ;;; Philip W. L. Fong ;;; SFU CMPT 310 (2001-1) ;;; ;; ;; Tail Recursions ;; (defun fast-triangular (N) "Compute the N'th triangular number." (fast-triangular-aux N 1)) (defun fast-triangular-aux (N A) "Compute the product of A and the N'th triangular number." (if (= N 1) A (fast-triangular-aux (1- N) (+ N A)))) (defun fast-power (B E) "Raise B to the E'th power." (fast-power-aux B E 1)) (defun fast-power-aux (B E A) "Compute the product of A and the E'th power of B." (if (zerop E) A (fast-power-aux B (1- E) (* B A)))) (defun fast-list-length (L) "Compute the length of list L." (fast-list-length-aux L 0)) (defun fast-list-length-aux (L A) "Compute the sum of A and the length of list L." (if (null L) A (fast-list-length-aux (rest L) (1+ A)))) ;; ;; Lambda Expressions ;; (defun apply-func-list (L X) "Apply a list L of functions to object X." (if (null L) X (funcall (first L) (apply-func-list (rest L) X)))) ;; 10 times the fourth element of the list (10 20 30 40 50) (apply-func-list (list #'(lambda (N) (* 10 N)) #'fourth) '(10 20 30 40 50)) ;; the third element of the second element in the list ;; ((1 2) (3 4 5) (6)) (apply-func-list (list #'third #'second) '((1 2) (3 4 5) (6))) ;; the difference between 10 and the length of (a b c d e f) (apply-func-list (list #'(lambda (N) (- 10 N)) #'list-length) '(a b c d e f)) ;; a list containing a list containing the symbol 'blah (apply-func-list (list #'list #'list) 'blah) ;; ;; Search Iteration ;; (defun find-nonempty (L) "Given a list L of lists, return the leftmost nonempty member." (if (null L) nil (if (not (null (first L))) (first L) (find-nonempty (rest L))))) (defun find-long-list (L) "Given a list L of lists, return the leftmost member with length at least 3." (find-if #'(lambda (X) (>= (list-length X) 3)) L)) (defun find-even-list (L) "Given a list L of lists, return the leftmost member with even length." (find-if #'(lambda (X) (evenp (list-length X))) L)) (defun find-divisible-by-three (L) "Given a list L of numbers, return the leftmost member that is divisible by 3." (find-if #'(lambda (X) (zerop (rem X 3))) L)) ;; ;; Filter Iteration ;; (defun list-remove-if (P L) "Return a list containing all elements of list L except for those satisfying predicate P." (if (null L) nil (if (funcall P (first L)) (list-remove-if P (rest L)) (cons (first L) (list-remove-if P (rest L)))))) (defun list-difference (L1 L2) "Compute the difference of lists L1 and L2." (remove-if #'(lambda (X) (member X L2)) L1)) ;; ;; Functions Returning Multiple Values ;; (defun list-min-max (L) "Given a list L of numbers, return two values, the minimum and the maximum members of L." (if (null L) (values nil nil) (list-min-max-aux (rest L) (first L) (first L)))) (defun list-min-max-aux (L MINIMUM MAXIMUM) "Given a list L of numbers, return (min LMIN MINIMUM) and (max LMAX MAXIMUM), where LMIN and LMAX are the minimum and maximum members of L respectively." (if (null L) (values MINIMUM MAXIMUM) (list-min-max-aux (rest L) (min (first L) MINIMUM) (max (first L) MAXIMUM))))