;; 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-intermediate-lambda-reader.ss" "lang")((modname week8_tu_full) (read-case-sensitive #t) (teachpacks ((lib "image.ss" "teachpack" "2htdp"))) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ((lib "image.ss" "teachpack" "2htdp"))))) ; Q1. First, a barrage of signature/lambda questions. ; What are the signatures for: ;(define (f x y) (+ x y)) ; Answer: ; f: number number -> number ;(define (f g x y) (g x y)) ; Answer: ; f: (X Y -> Z) X Y -> Z ;(define (f g x) (lambda (y) (g x y))) ; Answer: ; f: (X Y -> Z) X -> (Y -> Z) ;(define (f g x y) (lambda (z) (cond [(and (g x) (g y)) 7] ; [else z]))) ; Answer: ; f: (X -> boolean) X X -> (number -> number) ; Q2: Mutual Recursion. ; You're going to write a function using the starter code from Problem Set 6. ; The goal is to write a function that returns whether a family tree has a descendant ; satisfying a given condition, *and* also how far away that descendant is from ; the given family tree node. We'll break ; the problem into two subtasks, 2a and 2b, defined below. ; Starter code from Problem Set 6: ; a family-tree is: ; (make-parent list-of-family-tree symbol number symbol) (define-struct parent (children name date eyes)) ; Youngest Generation: (define Gustav (make-parent empty 'Gustav 1988 'brown)) (define Fred&Eva (list Gustav)) ; Middle Generation: (define Adam (make-parent empty 'Adam 1950 'yellow)) (define Dave (make-parent empty 'Dave 1955 'black)) (define Eva (make-parent Fred&Eva 'Eva 1965 'blue)) (define Fred (make-parent Fred&Eva 'Fred 1966 'pink)) (define Carl&Bettina (list Adam Dave Eva)) ; Oldest Generation: (define Carl (make-parent Carl&Bettina 'Carl 1926 'green)) (define Bettina (make-parent Carl&Bettina 'Bettina 1926 'green)) ; Question 2a: We want a function that returns not only whether ; a node with a given condition exists, but also how far away that node is. ; Define a data structure that captures both of these pieces of information. ; Answer: ; an ft-query-result is: ; - boolean ; - number (define-struct ft-query-result (found? distance)) ; Question 2b: Now change ft-satisfies (definition from class given below) ; to return not only whether ; a node in the tree meets a given condition, but also the distance (in number of generations) ; of the *nearest* such node. If the node isn't found, the function should return the depth of the search. ; You'll probably want two helper functions: one that increments the distance in ; the result, and another that selects the minimum distance of a set of ft-query-results. ; ft-satisfies : family-tree (family-tree -> boolean) -> boolean ; returns whether family tree has member satisfying condition (define (ft-satisfies ft p?) (or (p? ft) (lft-satisfies (parent-children ft) p?))) (check-expect (ft-satisfies Bettina (lambda (p) (> (parent-date p) 1980))) true) (check-expect (ft-satisfies Bettina (lambda (p) (< (parent-date p) 1800))) false) ; lft-satisfies : list-of-family-trees (family-tree -> boolean) -> boolean ; returns whether any of the list of family trees contains an element satisfying condition (define (lft-satisfies lft p?) (cond [(empty? lft) false] [else (or (ft-satisfies (first lft) p?) (lft-satisfies (rest lft) p?))])) (check-expect (lft-satisfies (list Bettina Carl) (lambda (p) (> (parent-date p) 1980))) true) (check-expect (lft-satisfies (list Bettina) (lambda (p) (symbol=? (parent-name p) 'george))) false) ; Answer: ; ft-satisfies-dist : family-tree (family-tree -> boolean) -> ft-query-result ; returns whether family tree has member satisfying condition, and its distance (or depth of search if not found) (define (ft-satisfies-dist ft p?) (cond[(p? ft) (make-ft-query-result true 0)] [else (increment-dist (lft-satisfies-dist (parent-children ft) p?))])) (check-expect (ft-satisfies-dist Bettina (lambda (p) (> (parent-date p) 1980))) (make-ft-query-result true 2)) (check-expect (ft-satisfies-dist Bettina (lambda (p) (> (parent-date p) 1940))) (make-ft-query-result true 1)) (check-expect (ft-satisfies-dist Bettina (lambda (p) (< (parent-date p) 1800))) (make-ft-query-result false 2)) ; lft-satisfies-dist : list-of-family-trees (family-tree -> boolean) -> ft-query-result ; returns whether any of the list of family trees contains an element satisfying condition (or depth of search if not found) (define (lft-satisfies-dist lft p?) (cond [(empty? lft) (make-ft-query-result false 0)] [else (min-found-list (map (lambda (x) (ft-satisfies-dist x p?)) lft))])) (define (increment-dist qr) (make-ft-query-result (ft-query-result-found? qr) (+ 1 (ft-query-result-distance qr)))) (define (min-found-list qrl) (foldr min-found-pair (make-ft-query-result false 0) qrl)) (define (min-found-pair x y) (cond [(not (ft-query-result-found? y)) x] [(not (ft-query-result-found? x)) y] [(< (ft-query-result-distance x) (ft-query-result-distance y)) x] [else y])) (check-expect (min-found-pair (make-ft-query-result true 3) (make-ft-query-result false 1)) (make-ft-query-result true 3)) (check-expect (min-found-pair (make-ft-query-result true 3) (make-ft-query-result true 1)) (make-ft-query-result true 1)) ; Lastly -- Note that the above question also touches on the return type used in our binary search ; code. Specifically, the increment-guesses function is similar to increment-dist.