;; 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-advanced-reader.ss" "lang")((modname week5_tu_full) (read-case-sensitive #t) (teachpacks ((lib "image.ss" "teachpack" "2htdp"))) (htdp-settings #(#t constructor repeating-decimal #t #t none #f ((lib "image.ss" "teachpack" "2htdp"))))) ; --------------Invariants------------------------------- ; A sorted-list is either ; - empty ; - (cons number[n] sorted-list[l]) ; INVARIANT: each number in `l' is greater than `n' ; Q1: Invariants. Use the design recipe to remove the least element of a sorted list. You may assume the list has at least one element. ; Be sure to exploit the sorted-list invariant! ; Answer: ; remove-least : sorted-list -> sorted-list ; Removes the least element in a sorted list (define (remove-least slist) (rest slist)) ; Notice how easy this is when we exploit the invariant. (check-expect (remove-least (list 1 2 3 4)) (list 2 3 4)) (check-expect (remove-least (list 2 4 10)) (list 4 10)) ; --------------Binary Search Trees------------------------------- ; 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)) ; 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)) (define mydb (make-db-node George (make-db-node Adam empty empty) (make-db-node Jon empty empty))) ; 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))) ; person-change-name : person symbol -> person ; changes the person's name (define (person-change-name per name) (make-person (person-ssn per) name)) ; Q2 : Write a function that takes a database, a name, and an ssn, and changes the name of the ; person with the given ssn to be the given name. It should return the same database, with this one change. ; You can use the quick three helper functions written above. ; Answer: ; name-change : database symbol number -> database ; returns database after changing the person with given ssn to have given name (define (name-change db name ssn) (cond[(empty? db) empty] [else (cond [(person-matches? (db-node-person db) ssn) (make-db-node (person-change-name (db-node-person db) name) (db-node-left db) (db-node-right db)) ] [(smaller? ssn (db-node-person db)) (make-db-node (db-node-person db) (name-change (db-node-left db) name ssn) (db-node-right db))] [else (make-db-node (db-node-person db) (db-node-left db) (name-change (db-node-right db) name ssn))])])) (check-expect (name-change mydb 'Clark 3) (make-db-node George (make-db-node Adam empty empty) (make-db-node (make-person 3 'Clark) empty empty))) (check-expect (name-change mydb 'Peter 0) mydb) ; --------------Multiple complex pieces of data------------------------------- ; Q3: Design a function that takes two lists of numbers, A and, and returns the set difference A - B. ; That is, it returns the numbers in list A but not in list B. You may assume the numbers in each list are unique. ; Answer: ; set-diff : list-of-numbers list-of-numbers -> list-of-numbers ; Returns the union of two lists of numbers (define (set-diff lon1 lon2) (cond [(empty? lon1) empty] [(empty? lon2) lon1] [else (cond [(member? (first lon1) lon2) (set-diff (rest lon1) lon2)] ;why lon2 and not (rest lon2) here? [else (cons (first lon1) (set-diff (rest lon1) lon2))])])) (check-expect (set-diff (list 1 2 3) (list 2 3 4)) (list 1)) (check-expect (set-diff (list 1 2) empty) (list 1 2))