;; Solutions for Andrew Plotkins "Lists and Lists" for the Z-Machine ;; GENIE: Your first problem is just to acquaint you with the ;; system. Start up the machine, and define twentyseven to have the ;; value 27. You can ask me to 'check' when you're ready, or ;; 'repeat' the problem if you need me to. (define twentyseven 27) ;; GENIE: Let's try creating some lists. Define values for cat and ;; dog so that cat and dog are equal? but not eqv?. Furthermore, ;; cdr(cat) and cdr(dog) must be eqv?. (define dog '(5)) (define cat '(5)) ;; GENIE: Perfect! There are actually two ways to solve this ;; problem. You used the simpler one, using one-term lists. The ;; trickier solution would be something like this: ;; (define tail '(end)) ;; (define cat (cons 'head tail)) ;; (define dog (cons 'head tail)) ;; The cdrs are eqv? because they are both the thing defined on the ;; first line. See?" ;; GENIE: Define abs to be the absolute value function for integers. ;; That is, (abs 4) should return 4; (abs -5) should return 5; and ;; (abs 0) should return 0. (define abs (lambda (x) (cond ((< x 0) (- x)) (t x)))) ;; GENIE: Define sum to be a function that adds up a list of ;; integers. So (sum '(8 2 3)) should return 13. Make sure it works ;; correctly for the empty list; (sum nil) should return 0. (define cadr (lambda (x) (car (cdr x)))) (define sum (lambda (ls) (cond ((null? ls) 0) ((= (length ls) 2) (+ (car ls) (cadr ls))) (t (+ (car ls) (sum (cdr ls))))))) ;; GENIE: This problem is like the last one, but more general. ;; Define megasum to add up an arbitrarily nested list of integers. ;; That is, (megasum '((8) 5 (2 () (9 1) 3))) should return 28. (define megasum (lambda (ls) (cond ((null? ls) 0) ((not (list? (car ls))) (+ (car ls) (megasum (cdr ls)))) (t (+ (megasum (car ls)) (megasum (cdr ls))))))) ;; GENIE: Define max to be a function that finds the maximum of a ;; list of integers. So (max '(5 14 -3)) should return 14. You can ;; assume the list will have at least one term. (define max-rec (lambda args (let ((max-elem (car args)) (ls (cadr args))) (cond ((null? ls) max-elem) ((> (car ls) max-elem) (max-rec (car ls) (cdr ls))) (t (max-rec max-elem (cdr ls))))))) (define max (lambda (ls) (max-rec (car ls) ls))) ;; GENIE: Last problem. You're going to define a function called ;; pocket. This function should take one argument. Now pay attention ;; here: pocket does two different things, depending on the ;; argument. If you give it nil as the argument, it should simply ;; return 8. But if you give pocket any integer as an argument, it ;; should return a new pocket function -- a function just like ;; pocket, but with that new integer hidden inside, replacing the 8. ;; >>(pocket nil) ;; 8 ;; >>(pocket 12) ;; [function] ;; >>(define newpocket (pocket 12)) ;; [function] ;; >>(newpocket nil) ;; 12 ;; >>(define thirdpocket (newpocket 3)) ;; [function] ;; >>(thirdpocket nil) ;; 3 ;; >>(newpocket nil) ;; 12 ;; >>(pocket nil) ;; 8 ;; Note that when you create a new pocket function, ;; previously-existing functions should keep working. (define pocket-gen (lambda (x) (letrec ((f (lambda (y) (cond ((null? y) x) (t (pocket-gen y)))))) f))) (define pocket (lambda (a) (cond ((null? a) 8) (t (pocket-gen a)))))