;; 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 lab9-solutions) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f () #f))) (define ENDS "Friends") (define MIES "Enemies") (define WORK "Work") (define TEAM "Football Team") (define GROUPS `(,ENDS ,MIES ,WORK ,TEAM)) (define-struct group [name people]) (define-struct user [name groups]) ; A SocialNetwork (SN) is a [Listof User]. ; A Group is a (make-group GroupName [Listof String]) ; Interpretation: name is the type of group, and ; people is the names of the users in that group. ; A GroupName is on GROUPS. ; A User is a (make-user String [Listof Group]) ; Interpretation: name is the user's name, and ; groups is a list of their groups of connections. ; examples (define amanda-ends (make-group ENDS '("Carlo" "Diya" "Fran"))) (define amanda-team (make-group TEAM '("Fran"))) (define amanda (make-user "Amanda" (list amanda-ends amanda-team))) (define bruce-ends (make-group ENDS '("Carlo" "Diya" "Emmi" "Fran" "Han"))) (define bruce-mies (make-group MIES '("Fran" "Diya" "Carlo"))) (define bruce-work (make-group WORK '("Carlo" "Amanda" "Diya" "Gregg"))) (define bruce (make-user "Bruce" (list bruce-ends bruce-mies bruce-work))) (define clo-team (make-group TEAM '("Amanda" "Fran"))) (define clo-ends (make-group ENDS '("Diya" "Han"))) (define clo-mies (make-group MIES '("Amanda"))) (define clo-work (make-group WORK '("Amanda"))) (define carlo (make-user "Carlo" (list clo-team clo-ends clo-mies clo-work))) (define diya-ends (make-group ENDS '("Emmi" "Fran" "Han"))) (define diya-mies (make-group MIES '("Fran" "Carlo"))) (define diya-work (make-group WORK '("Carlo" "Amanda"))) (define diya (make-user "Diya" (list diya-ends diya-mies diya-work))) (define emmi-ends (make-group ENDS '("Fran" "Han"))) (define emmi-team (make-group TEAM '("Carlo"))) (define emmi-mies (make-group MIES '("Carlo" "Diya" "Bruce" "Fran" "Han"))) (define emmi (make-user "Emmi" (list emmi-ends emmi-team emmi-mies))) (define fran-ends (make-group ENDS '("Gregg" "Han"))) (define fran-mies (make-group MIES '("Amanda" "Bruce" "Carlo"))) (define fran (make-user "Fran" (list fran-ends fran-mies))) (define gregg-mies (make-group MIES '("Han" "Bruce" "Fran"))) (define gregg-team (make-group TEAM '("Amanda" "Emmi"))) (define gregg-work (make-group WORK '("Amanda" "Carlo" "Diya"))) (define gregg (make-user "Gregg" (list gregg-mies gregg-team gregg-work))) (define han-ends (make-group ENDS '("Gregg"))) (define han-mies (make-group MIES '("Bruce" "Carlo"))) (define han (make-user "Han" (list han-ends han-mies))) (define irene-ends (make-group ENDS '("John"))) (define irene-team (make-group TEAM '("Katey"))) (define irene (make-user "Irene" (list irene-ends irene-team))) (define john-work (make-group WORK '("Katey"))) (define john (make-user "John" (list john-work))) (define katey-team (make-group TEAM '("Louis"))) (define katey (make-user "Katey" (list katey-team))) (define louis (make-user "Louis" '())) (define SN1 (list amanda bruce carlo diya emmi fran gregg han irene john katey louis)) ; LIBRARY FUNCTIONS ----------------------------------------------------------- ;; [Listof String] SN -> [Listof User] ;; Get the users with the given names (check-expect (get-users '("Amanda" "Diya" "Irene") SN1) (list amanda diya irene)) (define (get-users names sn) (map (λ (name) (get-user name sn)) names)) ;; String SN -> User ;; Get the user with the given name (check-expect (get-user "Diya" SN1) diya) (check-error (get-user "Tyler" SN1) "No user named Tyler") (define (get-user name sn) (local ;; User -> Boolean ;; Is user named name? [(define (named? user) (string=? name (user-name user)))] (cond [(empty? sn) (error (string-append "No user named " name))] [else (if (named? (first sn)) (first sn) (get-user name (rest sn)))]))) ;; User -> [Listof String] ;; Get all a user's friends (check-expect (all-friends amanda) '("Carlo" "Diya" "Fran")) (check-expect (all-friends bruce) '("Emmi" "Han" "Fran" "Carlo" "Amanda" "Diya" "Gregg")) (define (all-friends user) (local [(define (append-groups groups) (foldr (λ (group names) (append-unique (group-people group) names)) '() groups))] (append-groups (user-groups user)))) ;; [Listof String] [Listof String] -> [Listof String] ;; Append los2 to los1, removing duplicates (check-expect (append-unique '() '()) '()) (check-expect (append-unique '("a") '("a")) '("a")) (check-expect (append-unique '("ape" "banana" "cherry") '("dock" "banana" "ape" "star")) '("cherry" "dock" "banana" "ape" "star")) (define (append-unique los1 los2) (foldr (λ (s los) (if (member? s los) los (cons s los))) los2 los1)) ;; [Listof String] -> [Listof String] ;; Remove any duplicates from the list (check-expect (remove-duplicates '()) '()) (check-expect (remove-duplicates '("a" "b" "c")) '("a" "b" "c")) (check-expect (remove-duplicates '("a" "b" "a" "c" "a" "c")) '("b" "a" "c")) (define (remove-duplicates los) (foldr (λ (s l) (if (member? s l) l (cons s l))) '() los))