Solution to Programming Assignment #2

Last modified: "December 9, 1996 19:07:52 by matt"

From Graham's ANSI Common Lisp: Ch.5: 5,7; Ch.6: 3,7,8 (for 7 & 8 don't use a global variable); Ch.7: 3,4
5.5 Define iterative and recursive versions of a function that takes an object xand vector v, and returns a list of all the objects that immediately precede x in v:
> (precedes #\a "abracadabra")
(#\c #\d #\r)

(defun precedes-iter (keyChar string)
  (let ((prevChar nil)
	(result nil))
    (dotimes (curChar (length string) (remove-duplicates result))
      (when (and prevChar (eql keyChar (elt string curChar)))
	(push prevChar result))
      (setq prevChar (elt string curChar )))))

(defun precedes-recur (keyChar string)
  (when (> (length string) 1)
    (remove-duplicates
     (if (eql keyChar (elt string 1))		
	 (cons (elt string 0)			
	       (precedes-recur keyChar (subseq string 1))) 
       (precedes-recur keyChar (subseq string 1))))))
    

5.7 Define a function that takes a list of numbers and returns true iff the difference between each sucessive pair of them is 1, using

  1. recursion
  2. do
  3. mapc and return
(defun diff1-recur (lst)
  (if (> (length lst) 1)
      (and (= 1 (abs (- (car lst) (cadr lst))))
	   (diff1-recur (cdr lst)))
    t))

(defun diff1-iter (lst)
  (do ((curLst lst (cdr curLst)))
      ((<= (length curLst) 1) t)
    (if (/= 1 (abs (- (car curLst) (cadr curLst))))
	(return nil))))					

(defun diff1-mapc (lst)
  (mapc #'(lambda (prevTerm term)
	    (if (/= 1 (abs (- prevTerm term)))
		(return-from diff1-mapc nil)))
	lst (cdr lst))
  t)
	    

6.3 Define a function that takes any number of arguments and returns the number of arguments passed to it.

(defun counter (&rest args)
  (length args))					

6.7 Define a function that takes one argument, a number, and returns true if it is greater than the argument passed to the function the last time it was called. The function should return nil the first time it is called.

(let ((lastVal nil))
  (defun biggerThanLast-p (val)
    (let ((result (if lastVal
		    (> val lastVal)		
		    nil)))
      (setq lastVal val)
      result)))
6.8 Suppose expensive is a function of one argument, an integer between 0 and 100 inclusive, that returns the result of a time-consuming computation. Define a function frugal that returns the same answer, but only calls expensive when given an argument it has not seen before.

(let ((prevResults (make-array '(100) :initial-values nil)))
  (defun frugal (arg)
    (or (aref prevResults arg)
	(setf (aref prevResults arg) (expensive arg)))))

7.3 Suppose that in some format for text files, comments are indicated by a % character. Everything from this character to the end of the line is ignored. Define a function that takes two filenames, and writes to the second file a copy of the first, minus comments.

7.4 Define a function that takes a two-dimensional array of floats and displays it in neat columns. Each element should be printed with two digits after the decimal point, in a field 10 characters wide. (Assume all will fit.) You will need array-dimensions.