;; Data defn for list-of-nums-and-syms is in lect08.ss ;; Examples of list-of-nums-and-syms: empty (define raw-mallow (cons 'marshmallow empty)) (define roast-mallow (cons 'marshmallow (cons 1 empty))) (define stir-fry (cons 'onions (cons 'garlic (cons 2 (cons 'tofu (cons 8 (cons 'spinach (cons 1 empty)))))))) (define half-baked (cons 'nuts (cons 3 (cons 'salt (cons 1 (cons 'nuts empty)))))) ;; get-ingredients : list-of-nums-and-syms -> list-of-symbols ;; extracts a list of the symbols in the list ;; (define (get-ingredients a-lons) (cond [(empty? a-lons) ..] [(symbol? (first a-lons)) ..(first a-lons).. ..(get-ingredients (rest a-lons)).. ] [(number? (first a-lons)) ..(first a-lons).. ..(get-ingredients (rest a-lons)).. ])) (get-ingredients empty) = ... (get-ingredients raw-mallow) = ... (get-ingredients roast-mallow) = ... (get-ingredients stir-fry) = ... (get-ingredients half-baked) = ... ;; substitute : list-of-nums-and-syms sym sym -> list-of-nums-and-syms ;; replaces all uses of the first symbols with the second symbol ;; (define (substitute a-lons old-sym new-sym) (cond [(empty? a-lons) ..] [(symbol? (first a-lons)) ..(first a-lons).. ..(substitute (rest a-lons)).. ] [(number? (first a-lons)) ..(first a-lons).. ..(substitute (rest a-lons)).. ])) (substitute empty 'msg 'salt) = ... (substitute raw-mallow 'marshmallow 'egg) = ... (substitute roast-mallow 'marshmallow 'egg) = ... (substitute stir-fry 'tofu 'ground-chuck) = ... (substitute half-baked 'nuts 'nvts) = ... ;----------- (define-struct child (name ma pa birth-year)) ; A FamTree is: ; - 'unknown, or ; - (make-child ) ;; unknown: ANY --> boolean ;; Is val an unknown family tree? ;; (define (unknown? val) (and (symbol? val) (symbol=? 'unknown val))) (define (FamTree? val) (or (child? val) (unknown? val))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Examples ; We use place-holders to refer to particular trees. ; (define stone-age -2000000) (define barneys-tree (make-child 'barney 'unknown 'unknown (+ stone-age 100))) (define bambams-tree (make-child 'bam-bam (make-child 'betty 'unknown 'unknown (+ stone-age 105)) barneys-tree (+ stone-age 130))) (define barts-tree (make-child 'bart (make-child 'marge (make-child 'jackie 'unknown 'unknown 1926) 'unknown 1958) (make-child 'homer (make-child 'mona 'unknown 'unknown 1929) (make-child 'abe 'unknown 'unknown 1920) 1959) 1981)) ; Test cases. Comment this in/out as desired. ; (boolean=? (FamTree? 'unknown) true) (boolean=? (unknown? 'unknown) true) (boolean=? (child? 'unknown) false) (boolean=? (FamTree? barneys-tree) true) (boolean=? (unknown? barneys-tree) false) (boolean=? (child? barneys-tree) true) (boolean=? (FamTree? 'barney) false) (boolean=? (unknown? 'barney) false) (boolean=? (child? 'barney) false) (child-pa bambams-tree) = barneys-tree (symbol=? (child-name (child-pa (child-pa barts-tree))) 'abe) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; size: FamTree --> number ;; Given a FamTree "ft", return how many (non-unknown) children ft contains. ;; (define (size ft) (if (unknown? ft) 0 (+ (size (child-ma ft)) (size (child-pa ft)) 1))) ; Okay, now test size: (= (size 'unknown) 0) (= (size barneys-tree) 1) (= (size bambams-tree) 3) (= (size barts-tree) 4) ;------------ ;; related-to-abe?: FamTree --> boolean ;; Return wehther or not the name 'abe occurs in a-ft. ;; (Might better be named "descendent-of-abe?".) ;; (define (related-to-abe? a-ft) (cond [(unknown? a-ft) false] [(child? a-ft) (or (related-to-abe? (child-ma a-ft)) (related-to-abe? (child-pa a-ft)) (symbol=? (child-name a-ft) 'abe))])) ; Okay, now test related-to-abe?: (related-to-abe? 'unknown) = false (related-to-abe? barneys-tree) = false (related-to-abe? barts-tree) = true (related-to-abe? (make-child 'abe barneys-tree barneys-tree -4000)) = true ;------------ ;; height FamTree --> boolean ;; Return the maximum number of generations ;; which can be traced back along some path. ;; Somebody where we know the name, but no parents, counts as one generation. ;; (define (height a-ft) (cond [(unknown? a-ft) 0] [(child? a-ft) (add1 (max-of-2 (height (child-ma a-ft)) (height (child-pa a-ft))))])) ;; max-of-2: num, num --> num ;; Return the larger of {a, b} ;; (and, of course, if they're equal, return that number.) ;; (define (max-of-2 a b) (cond [(> a b) a] [(<= a b) b])) (= (max 2 3) 3) (= (max 0 -4) 0) (= (max 7 7) 7) (= (height 'unknown) 0) (= (height barneys-tree) 1) (= (height barts-tree) 3)