;; a person is a (make-person string number symbol list-of-person) (define-struct person (name year eye children)) ;; A list-of-person is either ;; empty, or ;; (cons person list-of-person) (define SusanTree (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)))) ; ;; there are 2 data definitions, so need 2 templates ; ; ;; person-template: person .. -> ... ; ;; ... ; (define (person-template aper ...) ; (person-name aper) ; (person-year aper) ; (person-eye aper) ; (lop-template (person-children aper)...)) ; ; ; ;; lop-template: list-of-person ... -> ... ; ;; ... ; (define (lop-template alop ...) ; (cond [(empty? alop) ] ; [(cons? alop) (person-template (first alop)...) ; (lop-template (rest alop) ...) ])) ;; count-older-blue: person number -> number ;; produces the number of blue-eyed people in the tree who were born before the given year (define (count-older-blue aper year) (cond [(and (< (person-year aper) year) (symbol=? (person-eye aper) 'blue)) (+ 1 (old-blue-descendants (person-children aper) year))] [else (old-blue-descendants (person-children aper) year)])) ;; old-blue-descendants: list-of-person number -> number ;; consumes a list of persons and produces the number of people in the list (and their descendants) who are blue-eyed ;; and born before the given year (define (old-blue-descendants alop year) (cond [(empty? alop) 0 ] [(cons? alop) (+ (count-older-blue (first alop) year) (old-blue-descendants (rest alop) year) ) ])) ;; test cases (check-expect (count-older-blue SusanTree 1950) 2) (check-expect (count-older-blue SusanTree 1941) 1)