;;; NKU CSC 601 - Fall 2002 - Kirby ;;; Scheme Warmup Exercises - Solutions ;;; ------------------------------------ (define tri-area ; Computes the area of a triangle. (lambda (base height) (* 1/2 base height))) (define sin5 ; Approximates the sine function using Taylor series to 5th order. (lambda (x) (+ x (/ (expt x 3) -6) (/ (expt x 5) 120)))) (define fac ; The factorial function n! (lambda (n) (if (< n 1) 1 (* n (fac (- n 1)))))) (define single? ; Is this a list with just one element? (lambda (s) (and (pair? s) (null? (cdr s))))) (define couple? ; Is this a list with just two elements? (lambda (s) (and (list? s) (single? (cdr s))))) (define average ; The average of a list of numbers. (lambda (s) (/ (apply + s) (length s)))) (define variance ; The variance of a list of numbers. (lambda (s) (let ((avg (average s))) (average (map (lambda (x) (expt (- x avg) 2)) s))))) (define all-equal? ; Are all elements of this list equal? (lambda (s) (or (null? s) (single? s) (and (equal? (car s) (cadr s)) (all-equal? (cdr s)))))) ;; Which of the following three versions (A,B,C) is better (if any)? Explain? (define gen-consecA ; Generate list of consecutive integers from 0 to n-1. (lambda (n) (if (zero? n) '() (cons 0 (map (lambda (x) (+ x 1)) (gen-consecA (- n 1))))))) (define gen-consecB ; Generate list of consecutive integers from 0 to n-1. (lambda (n) (if (zero? n) '() (append (gen-consecB (- n 1)) (list (- n 1)))))) (define gen-consecC ; Generate list of consecutive integers from 0 to n-1. (lambda (n) (gen-consec-any 0 (- n 1)))) (define gen-consec-any ; Generate list of consecutive integers from nstart to nstop. (lambda (nstart nstop) (if (> nstart nstop) () (cons nstart (gen-consec-any (+ 1 nstart) nstop))))) (define dup-each ; Duplicate each entry in a list. (lambda (s) (if (null? s) () (cons (car s) (cons (car s) (dup-each (cdr s))))))) (define count-atoms ; Count the atoms in a list. (lambda (s) (cond ((null? s) 0) ((pair? s) (+ (count-atoms (car s)) (count-atoms (cdr s)))) (#t 1)))) (define replace-atoms ; Replace the atoms in the list with '? (lambda (s) (cond ((null? s) ()) ((pair? s) (cons (replace-atoms (car s)) (replace-atoms (cdr s)))) (#t '?)))) (define domzero~ ; Return the function that is larger at 0. (lambda (f g) (if (> (f 0) (g 0)) f g))) (define or~ ; The predicate that results from the disjunction of several predicates. (lambda (predlist) (lambda (x) (if (null? predlist) #f (or ((car predlist) x) ((or~ (cdr predlist)) x)))))) (define multi-iter (lambda (f n) (lambda (x) (if (zero? n) (list x) (cons x ((multi-iter f (- n 1)) (f x))))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; TESTING ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (define cout ; For demonstrating functions. (lambda (s) (begin (display s) (display " ==> ") (display (eval s)) (newline)))) (begin (map cout '((tri-area 10 5) (sin5 0.1) (sin 0.1) (fac 5) (single? 4) (single? '(a)) (single? '(a b)) (single? '(a b c)) (couple? '(a)) (couple? '(a b)) (couple? '(a b c)) (average '(1 2 3 4 5)) (variance '(1 2 3 4 5)) (variance '(3 3 3 3 3)) (all-equal? '(a b c)) (all-equal? '(a a b a)) (all-equal? '(a a a a)) (gen-consecA 8) (gen-consecB 8) (gen-consecC 8) (dup-each '(a b c d)) (count-atoms '(a b (((c (e) f)) j ((j)) k) b)) (replace-atoms '(a b (((c (e) f)) j ((j)) k) b)) (domzero~ cos sin) (map (or~ (list odd? zero? positive?)) '(3 -3 0 4 -4)) ((multi-iter (lambda (x) (* 10 x)) 4) 7))) "That's all!")