;; Scheme code from Thursday of week 1 (9/4/08) ;; be sure you have tester.scm in the same ;; directory as this file (load "tester.scm") ;; first try at pow: big O(N) (define (pow1 b N) (cond [ (equal? N 0) 1 ] ;; could use =, equal? is general [ else (* b (pow1 b (- N 1))) ] )) ;; second try at pow: ALSO big O(N) (surprisingly!) (define (pow2 b N) (cond [ (equal? N 0) 1 ] ;; could use =, equal? is general [ (odd? N) (* b (pow2 b (- N 1))) ] [ else (* (pow2 b (/ N 2)) (pow2 b (/ N 2))) ] )) ;; third try at pow: now big O(log(N)) ~ much faster (define (pow3 b N) (cond [ (equal? N 0) 1 ] ;; could use =, equal? is general [ (odd? N) (* b (pow3 b (- N 1))) ] [ else (let* ( ;; let* allows nested definitions [ halfpow (pow3 b (/ N 2)) ] ) ;; although let would be ok here (* halfpow halfpow)) ] )) (test (pow1 3 5) 243) (test (pow2 3 5) 243) (test (pow3 3 5) 243) (test (pow1 3 0) 1) (test (pow2 3 0) 1) (test (pow3 3 0) 1) ;; recursion examples ;; because many of these are built-in to Scheme, we ;; change their names a little bit ;; redefining built-in functions is allowed, but dangerous ;; defining length: O(N) (define (len L) (cond [ (null? L) 0 ] [ else (+ 1 (len (rest L))) ] )) (test (len ()) 0) (test (len '(a b c d e f g)) 7) ;; defining member: O(N) (define (member2 e L) (cond [ (null? L) #f ] [ (equal? e (first L)) #t ] [ else (member2 e (rest L)) ] )) (test (member2 42 ()) #f) (test (member2 'g '(a b c d e f g)) #t) ;; defining remove: O(N) (define (rmv e L) (cond [ (null? L) () ] [ (equal? e (first L)) (rest L) ] [ else (cons (first L) (rmv e (rest L))) ] )) (test (rmv 42 '(41 42 43 42)) '(41 43 42)) (test (rmv 'h '(a b c d e f g)) '(a b c d e f g)) ;; the O(N**2) remove is probably not worth ;; reinforcing -- it replaces the base case above ;; with [ (not (member e L)) L ] ;; memAny e L: does e appear at any nesting level in L? ;; note that the equality check needs to be before the ;; list? check! (define (memAny e L) (cond [ (null? L) #f ] [ (equal? e (first L)) #t ] [ (list? (first L)) (or (memAny e (first L)) (memAny e (rest L))) ] [ else (memAny e (rest L)) ] )) (test (memAny '(1) '(0 2 ( (3 4 (1)) 5 6) 7 8)) #t) (test (memAny '(1) '(1)) #f) (test (memAny '(0) '(0 2 ( (3 4 (1)) 5 6) 7 8)) #f) ;; reverse (define (rev L) (cond [ (null? L) () ] [ else (append (rev (rest L)) (list (first L))) ] )) (test (rev '(4 5 6 7)) '(7 6 5 4)) (test (rev '()) '()) ;; flatten (define (flatten L) (cond [ (null? L) () ] [ (list? (first L)) (append (flatten (first L)) (flatten (rest L))) ] [ else (cons (first L) (flatten (rest L))) ] )) (test (flatten '( 1 2 (3 (4 (5 (((6)) 7 ) 8) 9 10)) 11)) '(1 2 3 4 5 6 7 8 9 10 11)) (test (flatten '()) '()) ;; this function computes log base 2 of N ;; (actually, it computes the largest integer ;; less than or equal to the log base 2 of N) (define (log2 N) (cond [ (< N 2) 0 ] [ else (+ 1 (log2 (quotient N 2))) ] )) ;; quotient is _integer_ division (ignoring remainer) (test (log2 2) 1) (test (log2 3) 1) (test (log2 4) 2) (test (log2 5) 2) (test (log2 6) 2) (test (log2 10) 3) (test (log2 1100) 10) ;; spf is included on the homework ;; here it is, as well... ;; spf is the "smallest prime factor" (define (spf N) (spf-from 2 N)) ;; call a helper function! ;; (spf-from low N) returns the smallest prime factor of N ;; that is greater than or equal to low ;; if (>= low N), then N is returned (define (spf-from low N) (cond [ (>= low N) N ] [ (equal? 0 (modulo N low)) low ] [ else (spf-from (+ low 1) N) ] )) (test (spf 30) 2) (test (spf 45) 3) ;; not possible to yield a 4! (test (spf 35) 5) (tester 'show)