;; 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 week9_f_full) (read-case-sensitive #t) (teachpacks ((lib "image.ss" "teachpack" "htdp"))) (htdp-settings #(#t constructor repeating-decimal #t #t none #f ((lib "image.ss" "teachpack" "htdp"))))) ;; a graph is: ;; (make-graph (listof X) (X -> (listof X)) (X X -> boolean)) (define-struct graph (nodes neighbor same-node?)) ; A ; / ; / ; B C ; |\ /| ; | \/ | ; D E F ; \ | / ; \|/ ; G ; (arrows pointing down) (define mygraph (make-graph '(a b c d e f g) (lambda (node) (cond [(symbol=? node 'a) '(b)] [(symbol=? node 'b) '(d e)] [(symbol=? node 'c) '(e f)] [(member node '(d e f)) '(g)] [(symbol=? node 'g) '()])) symbol=?)) ; route-exists : graph symbol symbol -> boolean ; returns whether a route exists from src to dest nodes in graph (define (route-exists? g src dest) (cond[((graph-same-node? g) src dest) true] [else (any-route-exists? g ((graph-neighbor g) src) dest)]) ) ; any-route-exists? : graph list-of-symbols symbol -> boolean ; returns whether any route exists from any of srcs to dest nodes in graph (define (any-route-exists? g srcs dest) (cond[(empty? srcs) false] [else (or (route-exists? g (first srcs) dest) (any-route-exists? g (rest srcs) dest))])) (check-expect (route-exists? mygraph 'a 'g) true) (check-expect (route-exists? mygraph 'g 'a) false) (check-expect (route-exists? mygraph 'b 'c) false) (define a-graph (make-graph '(x y z) (lambda (x) (cond [(symbol=? x 'x) '(y)] [(symbol=? x 'y) '(x)] [(symbol=? x 'z) '()])) symbol=?)) ; (route-exists? a-graph 'x 'z) ; = (any-route-exists a-graph '(y) 'z) ; = (or (route-exists? a-graph 'y 'z) ; (any-route-exists? g empty 'z)) ; = (or (any-route-exists a-graph '(x) 'z) ; (any-route-exists? g empty 'z)) ; = (or (or (route-exists? a-graph 'x 'z) ; (any-route-exists a-graph empty 'z)) ; (any-route-exists? g empty 'z)) ; route-exists?/a : graph symbol symbol list-of-symbols -> boolean ; returns whether any route exists from src to dest nodes in graph (define (route-exists?/a g src dest seen-so-far) (cond[((graph-same-node? g) src dest) true] [(already-seen? g src seen-so-far) false] [else (any-route-exists?/a g ((graph-neighbor g) src) dest (cons src seen-so-far))]) ) ; any-route-exists/a : graph list-of-symbols symbol -> boolean ; returns whether any route exists from any of srcs to dest nodes in graph (define (any-route-exists?/a g srcs dest seen-so-far) (cond[(empty? srcs) false] [else (or (route-exists?/a g (first srcs) dest seen-so-far) (any-route-exists?/a g (rest srcs) dest seen-so-far))])) ; already-seen? graph symbols list-of-symbols -> boolean ; determines whether node is in seen nodes according ; to graph-same-node function (define (already-seen? g node nodes) (cond [(empty? nodes) false] [else (or ((graph-same-node? g) (first nodes) node) (already-seen? g node (rest nodes)))])) (define (route-exists2? in out graph) (route-exists?/a in out graph empty)) (check-expect (route-exists2? mygraph 'a 'g) true) (check-expect (route-exists2? mygraph 'g 'a) false) (check-expect (route-exists2? mygraph 'b 'c) false) (check-expect (route-exists2? a-graph 'x 'z) false) (check-expect (route-exists2? a-graph 'x 'y) true)