;; The first three lines of this file were inserted by DrRacket. They record metadata ;; about the language level of this file in a form that our tools can easily process. #reader(lib "htdp-beginner-abbr-reader.ss" "lang")((modname week4_w_full) (read-case-sensitive #t) (teachpacks ((lib "image.ss" "teachpack" "htdp"))) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ((lib "image.ss" "teachpack" "htdp"))))) ; a list-of-numbers is: ; empty, or ; (cons number list-of-numbers) ; template: ; (define (fun-for-list-of-numbers numlist) ; (cond [(empty? numlist) ...] ; [(cons? numlist) ... (first numlist) ... (fun-for-list-of-numbers (rest numlist)) ... ]) ; Yesterday: ; count-doubles: list-of-numbers -> number ; returns the number of doubled elements in the list (define (count-doubles-old numlist) (cond [(empty? numlist) 0] [(empty? (rest numlist)) 0] [else (cond [(= (first numlist) (first (rest numlist))) (+ 1 (count-doubles (rest numlist)))] [else (count-doubles (rest numlist))] )]) ) ; Casey's simpler solution: ; count-doubles: list-of-numbers -> number ; returns the number of doubled elements in the list (define (count-doubles xs) (cond [(empty? xs) 0] [(cons? xs) (cond [(starts-with? (rest xs) (first xs)) (+ 1 (count-doubles (rest xs)))] [else (count-doubles (rest xs))])])) ; starts-with? : list-of-numbers number -> boolean ; Determines whether the first element of xs is x (define (starts-with? xs x) (cond [(empty? xs) false] [(cons? xs) (= (first xs) x)])) (check-expect (starts-with? (list 1 2) 1) true) (check-expect (starts-with? (list 1 2) 2) false) (check-expect (starts-with? empty 2) false) ; a person is ; - (make-person number symbol) (define-struct person (ssn name)) ;; example people: (define Adam (make-person 1 'adam)) (define George (make-person 2 'george)) (define Jon (make-person 3 'jon)) (define Steve (make-person 4 'steve)) ; Simple version: ; a database is ; - empty ; - (make-db-node person ; database ; database) ; Better version: ; a database is ; - empty ; - (make-db-node person ; database[left] ; database[right]) ; where everyone in [left] has a smaller ssn than person ; and everyone in [right] has a larger ssn than person (define-struct db-node (person left right)) ; template: ; (cond [(empty? db) ...] ; [(db-node? db) ; ... (db-node-person db) ... ; ... (fun-for-db (db-node-left db)) ... ; ... (fun-for-db (db-node-right db)) ... ]) ; lookup2 : number database -> person or false ; returns person if ssn in database, false otherwise (define (lookup2 n db) (cond [(empty? db) false] [(db-node? db) (cond [(person-matches? (db-node-person db) n) (db-node-person db)] [(smaller? n (db-node-person db)) (lookup2 n (db-node-left db))] [else (lookup2 n (db-node-right db))] ) ] ) ) ; helper functions: ; person-matches? : person number -> boolean ; returns whether person matches ssn (define (person-matches? per ssn) (= (person-ssn per) ssn)) ; smaller? : number person -> boolean ; returns whether number is smaller than person's ssn (define (smaller? n per) (< n (person-ssn per))) (define mydb (make-db-node George (make-db-node Adam empty empty) (make-db-node Steve (make-db-node Jon empty empty) empty))) (check-expect (lookup2 1 mydb) Adam) (check-expect (lookup2 2 mydb) George) (check-expect (lookup2 3 mydb) Jon) (check-expect (lookup2 4 mydb) Steve) (check-expect (lookup2 6 mydb) false) (check-expect (lookup2 2 empty) false)