(define title "Eureka! or the Naked Man in the Bath Tub") (define description "") ;; --------------------------------------------------------- ;; PROBLEM: what does quicksort do? ;; given a list of numbers, produce a sorted version ;; sort the numbers in ascending order ;; sort : [Listof Number] -> [Listof Number] ;; given: '(3 1 2) ;; wanted '(1 2 3) (define (sort lon) (cond [(empty? lon) empty] [else (insert (first lon) (sort (rest lon)))])) ;; place : Number [Listof Number] -> [Listof Number] ;; given: 3 and '(1 2) ;; wanted '(1 2 3) (define (insert n lon) (cond [(empty? lon) (list n)] [else (if (< n (first lon)) (cons n lon) (cons (first lon) (insert n (rest lon))))])) 'testing-insert (equal? (sort '(3 1 2)) '(1 2 3)) (equal? (sort '(3 1 2 0 4)) '(0 1 2 3 4)) ;; --------------------------------------------------------- ;; QUIZ: reformulate SORT using a loop ;; --------------------------------------------------------- ;; EUREKA! We could split the list into two halves: ;; -- the first one is all those numbers smaller than the first ;; -- the second one is all those numbers larger than the first ;; Then sort those and combine the rest. ;; sort.v2 : [Listof Number] -> [Listof Number] (define (sort.v2 lon) (cond [(empty? lon) empty] [else (local ((define pivot (first lon))) (append (sort.v2 (smallers pivot lon)) (equals pivot lon) (sort.v2 (largers pivot lon))))])) ;; smallers : Number [Listof Number] -> [Listof Number] ;; extract all those numbers from l that are smaller than pivot (define (smallers pivot l) (filter (lambda (x) (< x pivot)) l)) (define (largers pivot l) (filter (lambda (x) (> x pivot)) l)) (define (equals pivot l) (filter (lambda (x) (= x pivot)) l)) 'testing-v2 (equal? (sort.v2 '(3 1 2)) '(1 2 3)) (equal? (sort.v2 '(3 1 2 0 4)) '(0 1 2 3 4)) ;; explain different form of recursion to them ;; you may want to stop here. ;; --------------------------------------------------------- ;; PROBLEM: ;; shuffle a deck of cards; re-arrange them in some random order ;; [Listof X] -> [Listof X] (define (shuffle lox) (cond [(empty? lox) empty] [else (local ((define r (random (length lox)))) (cons (list-ref lox r) (shuffle (remove-pos r lox))))])) ;; Nat [Listof X] -> [Listof X] ;; remove the i-th element from lox (define (remove-pos i lox) (cond [(and (zero? i) (empty? lox)) empty] [(and (positive? i) (empty? lox)) (error 'remove-pos)] [(and (zero? i) (cons? lox)) (rest lox)] [else (cons (first lox) (remove-pos (sub1 i) (rest lox)))])) ;; TESTS (member (shuffle '(a b)) '((a b) (b a))) (member (shuffle '(a b c)) '((a b c) (b a c) (b c a) (a c b) (c a b) (c b a)))