;; Sid Stamm ;; C211 lab number 3: Looping & lists (car/cdr) ;; 9-18-2003 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; LISTS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; B (car ''x) (car (quote (quote x))) (car ''x) (cdr ''x) (cdr (quote (quote x))) (car '''x) (cdr '''x) ;; C: Nest them! (car (cdr '(a b))) ;;step-by-step, for the long & complex ;;(car (cdr (car (cdr '(a ((b (e f)) c)))))) (cdr '(a ((b (e f)) c))) ;; => (((b (e f)) c)) (car '(((b (e f)) c))) ;; => ((b (e f)) c) (cdr '((b (e f)) c)) ;; => (c) (car '(c)) ;; => c ;;Now, like scheme... All of these return the same thing: (car (cdr (car (cdr '(a ((b (e f)) c)))))) (car (cdr (car '(((b (e f)) c))))) (car (cdr '((b (e f)) c))) (car '(c)) 'c ;;this is how the REPL evaluates the expression, inside out. ;;E: Picking apart an IF expression (the same way Scheme does) (define a 2) (define b 3) (define if-exp '(if (> a b) a (+ a b))) (display if-exp) (eval if-exp) ;; pick it apart (car if-exp) (cdr if-exp) (car (cdr if-exp)) (cdr (cdr if-exp)) (car (cdr (cdr if-exp))) (cdr (cdr (cdr if-exp))) (car (cdr (cdr (cdr if-exp)))) ;; notice how the nth list item has n-1 cdr expressions? ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; LOOPING ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; This procedure calls itself forever. Be ready to press ^C (define chase-tail (lambda () (display "woof!") (newline) (chase-tail))) ;; This one has a base case: a stopping condition and a loop variable (define chase-tail-n (lambda (n) (unless (= 0 n) (display "woof!") (newline) (chase-tail-n (- n 1))))) ;change N ;; Another way to write it: (define chase-tail-n (lambda (n) (if (> n 0) (begin (display "woof!") (newline) (chase-tail-n (- n 1)))))) ;; Trace it, to see what happens (trace chase-tail-n) (chase-tail-n 5) ;;stop tracing (untrace chase-tail-n) ;; Write it with a counting function too ;; This one will return the number of loops it does ;; but you have to send it a starting point! (define chase-tail&count (lambda (n count) (if (= n 0) count (begin (display "woof!") (newline) (chase-tail&count (- n 1) (+ count 1)))))) (chase-tail&count 4 0) ;; Write a procedure to automatically pass in 0. (define chase-tail&count-from-zero (lambda (n) (chase-tail&count n 0))) (chase-tail&count-from-zero 4) ;; Why you'd want to print "Woof" a lot is beyond me... ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; LAB! Exercises ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Exercise 1: ;; ;; Write a procedure "combine" that takes a list of digits ;; like '(1 2 4 3) and returns the value if each was a digit ;; in a number. ;; ;; For example: ;; (combine '(6 2 3 4)) => 6234 ;; (combine '(1 9 9 9 9 9 9)) => 1999999 ;; ;; TOUGH BONUS: Modify the procedure so that it looks for a ;; colon, and turns it into a decimal point: ;; (combine '(1 2 : 4 5)) => 12.45 ;; (combine '(1 2 3 4 : 4 5 5)) => 1234.455 ;;answers: (define combine (lambda (ls) (if (null? ls) 0 (+ (combine (cdr ls)) (* (car ls) (expt 10 (length (cdr ls)))))))) ;;another way: (define combine (lambda (ls) (combine-helper ls 0))) (define combine-helper (lambda (ls accum) (if (null? ls) accum (combine-helper (cdr ls) (+ (car ls) (* 10 accum)))))) ;;colon-style (define combine: (lambda (ls) (combine:-helper ls 0 0))) (define combine:-helper (lambda (ls accum dec) (if (null? ls) (/ accum (expt 10 dec)) (if (eqv? (car ls) ':) (combine:-helper (cdr ls) accum (length (cdr ls))) (combine:-helper (cdr ls) (+ (car ls) (* 10.0 accum)) dec))))) ;; Exercise 2: ;; ;; Write a procedure called relationship ;; that takes two numbers and returns their ;; relationship: either < > or = ;; ;; (relationship 3 4) => < ;; (relationship 2 2) => = ;; (relationship 1000 2) => > ;answer (define relationship (lambda (x y) (if (> x y) '> (if (< x y) '< '=)))) ;; Exercise 3: ;; ;; Write a procedure called holds-true? ;; that takes an if-expression (as defined above) ;; and prints #t if the test-expression is true ;; and #f if not. ;; ;; (holds-true? '(if (> 3 4) 'sure 'no)) => #f ;answer (define holds-true? (lambda (if-expr) (eval (car (cdr if-expr)))))