Lecture 12, July 14

The lecture notes I post serve two purposes: to remind you of the topics we discussed and to provide any interesting code examples I did during lecture. I would describe these notes as an outline, not a summary, of what I talked about during lecture. You are not expected to be able to learn the material simply from examining these notes, nor is reading these notes a reasonable substitute for attending lecture.

Sorting Algorithms


; insert a number into a sorted list
; If the input is sorted, then the output will also be sorted
(: insert : Real (Listof Real) -> (Listof Real))
(define (insert n l)
  (cond
    [(empty? l) (list n)]
    [(< n (first l)) (cons n l)]
    [else (cons (first l) (insert n (rest l)))]))

(: isort : (Listof Real) -> (Listof Real))
;(define (isort l)
;  (cond
;    [(empty? l) '()]
;    [else (insert (first l) (isort (rest l)))]))
(define (isort l)
  (foldl insert '() l))

(isort (build-list 20 (λ ([n : Nonnegative-Integer]) (random 100))))

; Merges two lists into one
; If the input lists are sorted, then the output list is sorted
(: merge : (Listof Real) (Listof Real) -> (Listof Real))
(define (merge l m)
  (cond
    [(empty? l) m]
    [(empty? m) l]
    [(< (first l) (first m)) (cons (first l) (merge (rest l) m))]
    [else (cons (first m) (merge l (rest m)))]))

(: msort : (Listof Real) -> (Listof Real))
(define (msort l)
  (cond
    [(or (empty? l)
         (empty? (rest l))) l]
    [else
     (local
       {(: half-len : Integer)
        (define half-len (quotient (length l) 2))
        (: first-half : (Listof Real))
        (define first-half (take l half-len))
        (: second-half : (Listof Real))
        (define second-half (drop l half-len))}
       (merge (msort first-half)
              (msort second-half)))]))


(msort (build-list 20 (λ ([n : Nonnegative-Integer]) (random 100))))

(: qsort : (Listof Real) -> (Listof Real))
(define (qsort l)
  (cond
    [(empty? l) '()]
    [else
     (local
       {(: p : Real)
        (define p (first l))
        (: first-half : (Listof Real))
        (define first-half (filter (λ ([x : Real]) (< x p)) (rest l)))
        (: second-half : (Listof Real))
        (define second-half (filter (λ ([x : Real]) (>= x p)) (rest l)))}
       (append (qsort first-half)
               (cons p (qsort second-half))))]))


(qsort (build-list 20 (λ ([n : Nonnegative-Integer]) (random 100))))

Efficiency

Eliminating duplicated computations in recursive functions can create dramatically faster programs.

(: fib : Integer -> Integer)
(define (fib n)
  (cond
    [(<= n 1) 1]
    [else (+ (fib (- n 1)) (fib (- n 2)))]))

; Computes the nth fibbonaci number if a and b are both 1
(: fast-fib : Integer Integer Integer -> Integer)
(define (fast-fib n a b)
  (cond
    [(<= n 1) b]
    [else (fast-fib (- n 1) b (+ a b))]))

(: fib2 : Integer -> Integer)
(define (fib2 n)
  (local {(: fast-fib : Integer Integer Integer -> Integer)
          (define (fast-fib n a b)
            (cond
              [(<= n 1) b]
              [else (fast-fib (- n 1) b (+ a b))]))}
    (fast-fib n 1 1)))

(time (fib 37))
(time (fib2 37))