;; A person is a (make-person symbol number symbol list[person]) (define-struct person (name year eye children)) ;; A list[person] is either ;; - empty ;; - (cons person list[person]) (define tree1 (make-person 'Susan 1920 'blue (list (make-person 'Joe 1938 'green empty) (make-person 'Helen 1940 'brown (list (make-person 'Hank 1965 'green empty) (make-person 'Cara 1969 'brown empty))) (make-person 'Ricky 1942 'blue empty)))) ;; TEMPLATE #| (define (person-func adt) (person-name adt) ... (person-year adt) ... (person-eye adt) ... (traverse-lop (person-children adt)) ...) (define (traverse-lop plst) (cond [(empty? plst) ...] [(cons? plst) ... (person-func (first plst)) ... (traverse-lop (rest plst)) ...])) |# ;; count-older-blue : person number -> number ;; count how many blue eyed people in tree were born before given year (define (count-older-blue adt year) (cond [(and (< (person-year adt) year) (symbol=? (person-eye adt) 'blue)) (+ 1 (count-older-blue/plist (person-children adt) year))] [else (count-older-blue/plist (person-children adt) year)])) ;; count-older-blue/plst : list[person] number -> number ;; count how many blue eyed people in list were born before given year (define (count-older-blue/plist plst year) (cond [(empty? plst) 0] [(cons? plst) (+ (count-older-blue (first plst) year) (count-older-blue/plist (rest plst) year))])) ;; ------------------------------------- #| Here's how to think about the siblings? problem: the template tells you how to traverse the tree. Starting with that, we get ;; siblings? : symbol symbol person -> boolean ;; determine whether named people are children of same parent ;; in tree rooted at person (define (siblings? name1 name2 aper) (person-name aper) ... (person-eye aper) ... (person-year aper) ... (traverse-lop name1 name2 (person-children aper)) ... ) ;; traverse-lop : symbol symbol list[person] -> boolean ;; determine whether named people are children of some ;; common parent who is in the list of people (define (traverse-lop alop) (cond [(empty? alop) ...] [(cons? alop) (siblings? name1 name2 (first alop)) ... (traverse name1 name2 (rest alop)) ... ])) Start by filling this in. The traverse-lop function is relatively easy, because it checks for siblings starting from each person in the list. For the siblings? function, we need to check whether the current person is the common parent, and traverse the rest of the tree if not. |# ;; siblings? : symbol symbol person -> boolean ;; determine whether named people are children of same parent ;; in tree rooted at person (define (siblings? name1 name2 aper) (or (has-children-named? name1 name2 aper) (traverse-lop name1 name2 (person-children aper)))) ;; traverse-lop : symbol symbol list[person] -> boolean ;; determine whether named people are children of some ;; common parent who is in the list of people (define (traverse-lop alop) (cond [(empty? alop) false] [(cons? alop) (or (siblings? name1 name2 (first alop)) (traverse name1 name2 (rest alop)))])) ;; Now we just need to implement has-children-named?. ;; has-children-named? : symbol symbol person -> boolean ;; determine whether person has children with given names (define (has-children-named? name1 name2 aper) (local ((define (kidnames (map person-name (person-children aper)))) (and (in-list? name1 kidnames) (in-list? name2 kidnames)))) ;; in-list? : symbol list[symbol] -> boolean ;; determines whether symbol is in list (define (in-list? name namelist) (not (empty? (filter (lambda (n) (symbol=? n name)) namelist)))) #| What this problem teaches you: The templates traverse data structures. You may need additional functions to process the data at each point in the structure, as we did with has-children-named?, and those functions may be recursive (as in-list? was). In general, use the template to walk the list, then ask how to process each node. If you tried to scan for children in the template code, you probably got into a bit of a mess. You can't traverse a list for two purposes in one function. Walking the tree and searching for children's names are two purposes, so you needed two functions over lists of people. |#