;; 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 week8_w_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"))))) ; graphs ;; a graph is: ;; (make-graph (listof symbol) (symbol -> (listof symbol))) (define-struct graph (nodes neighbor)) ; 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) '()])))) (define mygraph2 (make-graph '(a b c d e f g) (lambda (node) (cond [(symbol=? node 'a) '(b)] [(symbol=? node 'b) '(d e)] [(symbol=? node 'c) '(d e f)] [(member node '(d e f)) '(g)] [(symbol=? node 'g) '()])))) ;; add-edge : graph symbol symbol -> graph ; adds edge to graph from a to b (define (add-edge g a b) (make-graph (graph-nodes g) (lambda (x) (cond [(symbol=? x a) (cons b ((graph-neighbor g) x))] [else ((graph-neighbor g) x)])))) (check-expect (graph=? (add-edge mygraph 'c 'd) mygraph2) true) (check-expect (graph=? (add-edge mygraph 'c 'd) mygraph) false) ;; graph=? : graph graph -> boolean ; returns whether two graphs are equal (define (graph=? g1 g2) (and (equal? (graph-nodes g1) (graph-nodes g2)) (all-true (map (lambda (node) (neighbors-equal g1 g2 node)) (graph-nodes g1))))) ;wishlist: ; all-true ; neighbors-equal (define g1 (make-graph (list 'a 'b) (lambda (x) (cond[(symbol=? x 'a) '(b)] [else '()])))) (define g2 (make-graph (list 'a 'b) (lambda (x) (cond[(symbol=? x 'a) '(b)] [else '()])))) (define g3 (make-graph (list 'a 'b) (lambda (x) (cond[(symbol=? x 'b) '(a)] [else '()])))) (check-expect (graph=? g1 g2) true) (check-expect (graph=? g1 mygraph) false) (check-expect (graph=? g3 g1) false) ; neighbors-equal : graph graph node -> boolean ; returns true if neighbors are the same for node in graphs (define (neighbors-equal g1 g2 a) (lists-same-elements ((graph-neighbor g1) a) ((graph-neighbor g2) a))) (check-expect (neighbors-equal g1 g2 'a) true) (check-expect (neighbors-equal g1 g3 'a) false) ;lists-same-elements : list-of-X list-of-X -> boolean ; returns whether the lists contain the same elements, ignoring order and duplication (define (lists-same-elements a b) (and (a-contains-b a b) (a-contains-b b a))) (check-expect (lists-same-elements (list 1 2) (list 2 1)) true) (check-expect (lists-same-elements (list 1 2) (list 3 1)) false) (check-expect (lists-same-elements (list 1 2) (list 3 1 2)) false) ; a-contains-b : list-of-X list-of-X -> boolean ; returns whether the first list contains all elements in the second list, ignoring duplication (define (a-contains-b a b) (all-true (map (lambda (x) (member? x a)) b))) (check-expect (a-contains-b (list 1 2) (list 2 1)) true) (check-expect (a-contains-b (list 1 2) (list 3 1)) false) (check-expect (a-contains-b (list 3 1 2) (list 1 2)) true) ; all-true : list-of-boolean -> boolean ; returns true if all booleans are true, or list is empty (define (all-true lob) (cond [(empty? lob) true] [else (and (first lob) (all-true (rest lob)))] )) (check-expect (all-true (list true true)) true) (check-expect (all-true (list true false)) false)