Ich lese gerade das Buch „ANSI Common Lisp“ von Paul Graham und veröffentliche hier meine Lösungen zu den Übungen am Ende der Kapitel. Hier sind meine Lösungen zu Kapitel 5.
Übung 1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
;;; (a) (defun exercise-1a-before (y) (let ((x (car y))) (cons x x))) (exercise-1a-before '(a b c)) ; (A . A) (defun exercise-1a-after (y) ((lambda (x) (cons x x)) (car y))) (exercise-1a-after '(a b c)) ; (A . A) ;;; (b) (defun exercise-1b-before (x z) (let* ((w (car x)) (y (+ w z))) (cons w y))) (exercise-1b-before '(1 2 3) 5) ; (1 . 6) (defun exercise-1b-after (x z) ((lambda (w) ((lambda (y) (cons w y)) (+ w z))) (car x))) (exercise-1b-after '(1 2 3) 5) ; (1 . 6) |
Übung 2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
;;; Das Original (defun mystery (x y) (if (null y) nil (if (eql (car y) x) 0 (let ((z (mystery x (cdr y)))) (and z (+ z 1)))))) (mystery 'a '(b c a d e a a f a)) (mystery 'x '(b c d e a a f a)) ;;; Lösung (defun mystery-cond (x y) (cond ((null y) nil) ((eql (car y) x) 0) (t (let ((z (mystery x (cdr y)))) (and z (+ z 1)))))) (mystery-cond 'a '(b c a d e a a f a)) ; 2 (mystery 'x '(b c d e a a f a)) ; NIL |
Übung 3:
1 2 3 4 5 6 7 8 |
(defun square-5 (x) (if (<= x 5) nil (* x x))) (square-5 1) ; nil (square-5 5) ; nil (square-5 6) ; 36 |
Übung 4:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
;;; Original (defconstant month #(0 31 59 90 120 151 181 212 243 273 304 334 365)) (defun leap? (y) (and (zerop (mod y 4)) (or (zerop (mod y 400)) (not (zerop (mod y 100)))))) (defun month-num (m y) (+ (svref month (- m 1)) (if (and (> m 2) (leap? y)) 1 0))) (month-num 1 2000) ; 0 (month-num 2 2000) ; 31 (month-num 3 2000) ; 68 ;;; Lösung (defun month-num-new (m y) (+ (case m (1 0) (2 31) (3 59) (4 90) (5 120) (6 151) (7 181) (8 212) (9 243) (10 273) (11 304) (12 334) (otherwise 365)) (if (and (> m 2) (leap? y)) 1 0))) (month-num-new 1 2000) ; 0 (month-num-new 2 2000) ; 31 (month-num-new 3 2000) ; 60 (month-num-new 4 2000) ; 91 (month-num-new 5 2000) ; 121 (month-num-new 6 2000) ; 152 (month-num-new 7 2000) ; 182 (month-num-new 8 2000) ; 213 (month-num-new 9 2000) ; 244 (month-num-new 10 2000) ; 274 (month-num-new 11 2000) ; 305 (month-num-new 12 2000) ; 335 (month-num-new 13 2000) ; 366 |
Übung 5:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
;;; Iterativ (defun precedes-iter (el vec) (if (< (length vec) 2) nil (let ((result nil)) (do ((i 1 (+ i 1)) (e (aref vec 0) (aref vec i))) ((= i (length vec)) (reverse result)) (if (equal el (aref vec i)) (push e result)))))) (precedes-iter 1 #()) ; nil (precedes-iter 1 #(1)) ; nil (precedes-iter 1 #(1 2)) ; nil (precedes-iter 1 #(2 1)) ; (2) (precedes-iter 4 #(1 4 6 4)) ; (1 6) (precedes-iter #\a "abracadabra") ; (#\r #\c #\d #\r) ;;; Rekursiv (defun precedes-rec-internal (el vec i result) (if (= i (length vec)) result (progn (if (equal el (aref vec i)) (push (aref vec (- i 1)) result)) (precedes-rec-internal el vec (+ i 1) result)))) (defun precedes-rec (el vec) (if (< (length vec) 2) nil (reverse (precedes-rec-internal el vec 1 nil)))) (precedes-rec 1 #()) ; nil (precedes-rec 1 #(1)) ; nil (precedes-rec 1 #(1 2)) ; nil (precedes-rec 1 #(2 1)) ; (2) (precedes-rec 4 #(1 4 6 4)) ; (1 6) (precedes-rec #\a "abracadabra") ; (#\r #\c #\d #\r) |
Übung 6:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
;;; Iterativ (defun intersperse-iter (el lst) (let ((len (length lst)) (res nil) (ls lst)) (if (< len 2) lst (do* ((i 1 (+ i 1)) (ls ls (cdr ls)) (e (car ls) (car ls))) ((= len i) (push e res)) (push e res) (push el res))) (reverse res))) (intersperse-iter '- '(a b c d)) ; (A - B - C - D) ;;; Rekursiv (defun intersperse-rec (el lst) (if (null lst) nil (cons (car lst) (if (> (length lst) 1) (cons el (intersperse-rec el (cdr lst))) (car (cdr lst))))))) (intersperse-rec '- '(a b c d)) ; (A - B - C - D) |
Übung 7:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
;;; (a) Rekursiv (defun num-diff-1-rec-internal (lst former) (cond ((null lst) t) ((= (- (car lst) former) 1) (num-diff-1-rec-internal (cdr lst) (car lst))) (t nil))) (defun num-diff-1-rec (lst) (if (or (null lst) (null (cdr lst))) nil (num-diff-1-rec-internal (cdr lst) (car lst)))) (num-diff-1-rec nil) ; nil (num-diff-1-rec '(2)) ; nil (num-diff-1-rec '(2 3)) ; t (num-diff-1-rec '(2 3 4 5 6)) ; t (num-diff-1-rec '(2 3 5 6 7)) ; nil ;;; (b) Iterativ (defun num-diff-1-iter (lst) (if (or (null lst) (null (cdr lst))) nil (do ((res t (and res (= (- (second lst) (first lst)) 1))) (lst lst (cdr lst))) ((null (cdr lst)) res)))) (num-diff-1-iter nil) ; nil (num-diff-1-iter '(2)) ; nil (num-diff-1-iter '(2 3)) ; t (num-diff-1-iter '(2 3 4 5 6)) ; t (num-diff-1-iter '(2 3 5 6 7)) ; nil ;;; (c) mapc return (defun num-diff-1-mapc (lst) (if (or (null lst) (null (cdr lst))) nil (let ((former (first lst))) (mapc #'(lambda (next) (progn (if (/= (- next former) 1) (return-from num-diff-1-mapc nil)) (setf former next))) (cdr lst)) t))) (num-diff-1-mapc nil) ; nil (num-diff-1-mapc '(2)) ; nil (num-diff-1-mapc '(2 3)) ; t (num-diff-1-mapc '(2 3 4 5 6)) ; t (num-diff-1-mapc '(2 3 5 6 7)) ; nil |
Übung 8:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
(defun maxmin-internal (vec len i max min) (if (= i len) (values max min) (let ((a (svref vec i))) (maxmin-internal vec len (+ i 1) (if (> a max) a max) (if (< a min) a min))))) (defun maxmin (vec) (if (or (null vec) (zerop (length vec))) nil (let ((a (svref vec 0))) (maxmin-internal vec (length vec) 1 a a)))) (maxmin #(3 20 4 6 15 7 4 9 10)) ; 20, 3 (maxmin #(1)) ; 1, 1 (maxmin #()) ; nil (maxmin nil) ; nil |