;;; 1. ;;; a) ;;; Dot is a special syntax in Lisp for dotted pairs and dotted lists; ;;; so it cannot be printed as a symbol using (print .), which would ;;; be interpreted as an incomplete dotted pair, thus generating a ;;; syntax error; though, a dot can be printed as a string, character, ;;; or one of two varieties of escaped symbols. ;;; On the other side, print cannot be used for dots, as it is printing ;;; Lisp-readable expressions, so that it has to mark the type of the ;;; output using quotes and escapes; so you need to use princ, which is ;;; solving the same task, just that it prints in user-readable format, ;;; so that the dot will not have quotes or escapes. ;;; ;;; (princ ".") ; as a string ;;; (princ #\.) ; as a characte ;;; (princ \.) ; as a symbol with an escaped character ;;; (princ |.|) ; as a completely escaped symbol (defun dots-iter (count) (dotimes (i count) (princ ".") ) ) ;;; using progn ;;; (progn ;;; s-expr-1 ;;; s-expr-2 ;;; ... ;;; s-expr-n ;;; ) ;;; progn evaluates the s-expresions in sequence and returns the result ;;; of the last one. (defun dots-rec (count) (if (> count 0) (progn (princ ".") (dots-rec (1- count)) ) ) ) ;;; or, using when ;;; (when cond ;;; s-expr-1 ;;; s-expr-2 ;;; ... ;;; s-expr-n ;;; ) ;;; when is exactly as an if with no else, but a progn containing all the ;;; s-expressions as then. Thus, if cond is non-nil, it evaluates the ;;; s-expressions in sequence and returns the result of the last one; if ;;; cond is nil, then it returns nil. ;;; When you don't have an else brach, it is best to use when. (defun dots-rec (count) (when (> count 0) (princ ".") (dots-rec (1- count)) ) ) ;;; or, of course, you can use cond; but in this case, when is the best. ;;; It is not a good idea to use more complex constructs when you don't ;;; need them, as it would complicate the code for both the human reader ;;; and the compiler. ;;; GENERAL NOTE REGARDING 1.a) ;;; Many of you were concerned by the extra line of text you get when this ;;; function (either version) runs. That line is the result of the function ;;; call, which is printed automatically by the Lisp interpreter. In order ;;; to deactivate printing of the result, just return (values), which is a ;;; Lisp form that can pack multiple values in a single value, but in this ;;; case is used without any value, so that it returns 'no value'. (defun dots-iter-noval (count) (dotimes (i count (values)) (princ ".") ) ) (defun dots-rec-noval (count) (when (> count 0) (princ ".") (dots-rec-noval (1- count)) ) (values) ) ;;; b) (defun count-iter (lst symbol) (let ((count 0) ) (dolist (elm lst count) (when (eql elm symbol) (incf count) ; incf increments the argument ;; or (setf count (1+ count)) ) ) ) ) (defun count-rec-1 (lst symbol) (if lst ; is lst not null? (+ (if (eql (first lst) symbol) 1 0) (count-rec-1 (rest lst) symbol) ) 0 ) ) ;; or (defun count-rec-1b (lst symbol) (if lst ; is lst not null? (if (eql (first lst) symbol) (1+ (count-rec-1b (rest lst) symbol)) (count-rec-1b (rest lst) symbol) ) 0 ) ) ;; or (defun count-rec-2 (lst symbol &optional (count 0)) (if lst ; is lst not null? (count-rec-2 (rest lst) symbol (+ count (if (eql (first lst) symbol) 1 0)) ) count ) ) ;; or (defun count-rec-2b (lst symbol &optional (count 0)) (if lst ; is lst not null? (if (eql (first lst) symbol) (count-rec-2b (rest lst) symbol (1+ count)) (count-rec-2b (rest lst) symbol count) ) count ) ) ;;; 2. (defun pos+-rec (lst &optional (count 0)) (when lst (cons (+ (first lst) count) (pos+-rec (rest lst) (1+ count)) ) ) ) (defun pos+-iter (lst) (do ((newlist nil) (count 0 (1+ count)) (tail lst (rest tail)) ) ((null tail) (reverse newlist)) (push (+ count (first tail)) newlist) ;; or (setf newlist (cons (+ count (first tail)) newlist)) ) ) (defun pos+-mapcar (lst) (let ((count -1) ;; one step before 0 ) (mapcar #'(lambda (elm) (incf count) (+ count elm) ) lst ) ) ) ;;; 3. (defun my-remove (elm lst) (when lst ; is lst not null? (let ((cleaned-tail (my-remove elm (rest lst))) ) (if (eql elm (first lst)) cleaned-tail (cons (first lst) cleaned-tail) ) ) ) ;; if lst is null, when returns null ) ;;; 4. (let ((max nil) ) (defun f (value) (if (or (null max) (< max value)) (setf max value) ; this also returns the new value of max max ) ) ) ;;; 5. ;;; a) representation (root (left subtree) (right subtree)) ;;; ;;; data type equation: ;;; ;;; tree = nil ;;; | atom ;;; | (atom tree tree); ;;; (defun preorder (tree) (cond ((null tree) nil) ((atom tree) (list tree)) (t (append (list (first tree)) ; root (preorder (second tree)) ; preorder of left subtree (preorder (third tree)) ; preorder of right subtree )) ) ) (defun inorder (tree) (cond ((null tree) nil) ((atom tree) (list tree)) (t (append (inorder (second tree)) ; inorder of left subtree (list (first tree)) ; root (inorder (third tree)) ; inorder of right subtree )) ) ) (defun postorder (tree) (cond ((null tree) nil) ((atom tree) (list tree)) (t (append (postorder (second tree)) ; postorder of left subtree (postorder (third tree)) ; postorder of right subtree (list (first tree)) ; root )) ) ) ;;; or, with generic algorithm factoring (defun traverse (func tree) (cond ((null tree) nil) ((atom tree) (list tree)) (t (funcall func tree)) ) ) (defun preorder-node (tree) (append (list (first tree)) ; root (preorder-1 (second tree)) ; preorder of left subtree (preorder-1 (third tree)) ; preorder of right subtree ) ) (defun preorder-1 (tree) (traverse #'preorder-node tree) ) (defun inorder-node (tree) (append (inorder-1 (second tree)) ; inorder of left subtree (list (first tree)) ; root (inorder-1 (third tree)) ; inorder of right subtree ) ) (defun inorder-1 (tree) (traverse #'inorder-node tree) ) (defun postorder-node (tree) (append (postorder-1 (second tree)) ; postorder of left subtree (postorder-1 (third tree)) ; postorder of right subtree (list (first tree)) ; root ) ) (defun postorder-1 (tree) (traverse #'postorder-node tree) ) ; or, only for the bold (defun traverse-2 (func tree) (cond ((null tree) nil) ((atom tree) (list tree)) (t (funcall func tree #'traverse-2)) ) ) (defun preorder-node-2 (tree traversor) (append (list (first tree)) ; root (funcall traversor #'preorder-node-2 (second tree)) ; preorder of left subtree (funcall traversor #'preorder-node-2 (third tree)) ; preorder of right subtree ) ) (defun preorder-2 (tree) (traverse-2 #'preorder-node-2 tree) ) (defun inorder-node-2 (tree traversor) (append (funcall traversor #'inorder-node-2 (second tree)) ; inorder of left subtree (list (first tree)) ; root (funcall traversor #'inorder-node-2 (third tree)) ; inorder of right subtree ) ) (defun inorder-2 (tree) (traverse-2 #'inorder-node-2 tree) ) (defun postorder-node-2 (tree traversor) (append (funcall traversor #'postorder-node-2 (second tree)) ; postorder of left subtree (funcall traversor #'postorder-node-2 (third tree)) ; postorder of right subtree (list (first tree)) ; root ) ) (defun postorder-2 (tree) (traverse-2 #'postorder-node-2 tree) ) ;;; b) representation: association lists (defun traverse-assoc (tree func &optional (node-name (first (first tree)))) (if (null node-name) nil (let ((node (assoc node-name tree)) ) (if (null node) (list node-name) ; leaf (funcall func node tree) ) ) ) ) (defun preorder-node-assoc (node tree) (append (list (first node)) ; root (preorder-assoc tree (second node)) ; preorder of left subtree (preorder-assoc tree (third node)) ; preorder of right subtree ) ) (defun preorder-assoc (tree &optional (node-name (first (first tree)))) (traverse-assoc tree #'preorder-node-assoc node-name) ) (defun inorder-node-assoc (node tree) (append (inorder-assoc tree (second node)) ; inorder of left subtree (list (first node)) ; root (inorder-assoc tree (third node)) ; inorder of right subtree ) ) (defun inorder-assoc (tree &optional (node-name (first (first tree)))) (traverse-assoc tree #'inorder-node-assoc node-name) ) (defun postorder-node-assoc (node tree) (append (postorder-assoc tree (second node)) ; postorder of left subtree (postorder-assoc tree (third node)) ; postorder of right subtree (list (first node)) ; root ) ) (defun postorder-assoc (tree &optional (node-name (first (first tree)))) (traverse-assoc tree #'postorder-node-assoc node-name) ) ;; or, (defun preorder-assoc-2 (tree &optional (node-name (first (first tree)))) (if (null node-name) nil (let ((node (assoc node-name tree)) ) (if (null node) (list node-name) ; leaf (append (list (first node)) (preorder-assoc-2 tree (second node)) (preorder-assoc-2 tree (third node)) ) ) ) ) ) (defun inorder-assoc-2 (tree &optional (node-name (first (first tree)))) (if (null node-name) nil (let ((node (assoc node-name tree)) ) (if (null node) (list node-name) ; leaf (append (inorder-assoc-2 tree (second node)) (list (first node)) (inorder-assoc-2 tree (third node)) ) ) ) ) ) (defun postorder-assoc-2 (tree &optional (node-name (first (first tree)))) (if (null node-name) nil (let ((node (assoc node-name tree)) ) (if (null node) (list node-name) ; leaf (append (postorder-assoc-2 tree (second node)) (postorder-assoc-2 tree (third node)) (list (first node)) ) ) ) ) )