;; 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 Lab8-part1-solutions) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f () #f))) ; Lab 8 ; PART 1 SOLUTIONS ; A User is a (make-user String [Listof String] [Listof String]) (define-struct user [name friends enemies]) ; where name is the user's name, friends are the user's friends, ; classmates are the user's enemies. ; A SocialNetwork (SN) is a [Listof User] ; examples (define amanda (make-user "Amanda" '("Carlo" "Diya" "Fran") '())) (define bruce (make-user "Bruce" '("Carlo" "Diya" "Emmi" "Fran" "Han") '("Fran" "Diya" "Carlo"))) (define carlo (make-user "Carlo" '("Diya" "Han") '("Amanda"))) (define diya (make-user "Diya" '("Emmi" "Fran" "Han") '("Fran" "Carlo"))) (define emmi (make-user "Emmi" '("Fran" "Han") '("Carlo" "Diya" "Bruce" "Fran" "Han"))) (define fran (make-user "Fran" '("Gregg" "Han") '("Amanda" "Carlo"))) (define gregg (make-user "Gregg" '() '("Han" "Bruce" "Fran"))) (define han (make-user "Han" '("Gregg") '("Bruce" "Carlo"))) (define SN1 (list amanda bruce carlo diya emmi fran gregg han)) ; Exercise 1 ; remove-user : User SN -> SN ; Removes the given User from the SocialNetwork. (define (remove-user u sn) (local (; Filter loop body: X = User ; User -> Boolean ; Keep the user if its name is not the one we want to remove ; if u = "Suzanne", given amanda, expect #false ; if u = "Amanda", given amanda, expect #true (define (remove-single-user usr) (not (string=? (user-name usr) (user-name u)))) ; Map loop body: X = User, Y = User ; User -> User ; Remove occurences of u from the given User's friends and enemies. ; if u = "Suzanne", given '("Amanda" "Bruce"), expect '("Amanda" "Bruce") ; if u = "Amanda", given '("Amanda" "Bruce"), expect '("Bruce") (define (remove-references usr) (make-user (user-name usr) (drop (user-name u) (user-friends usr)) (drop (user-name u) (user-enemies usr))))) (filter remove-single-user (map remove-references sn)))) (check-expect (remove-user amanda SN1) (append (list bruce) (list (make-user "Carlo" (user-friends carlo) '())) (list diya emmi) (list (make-user "Fran" (user-friends fran) '("Carlo"))) (list gregg han))) (check-expect (remove-user (make-user "Suzanne" '("Amanda") '("Bruce")) SN1) SN1) ; Exercise 2 ; count-friendships : String SN -> N ; Count the friend connections that other users have to the given user. (define (count-friendships uname sn) (local (; foldr: X = User, Y = Natural ; Count the friend connections that the given User has to uname, ; and add to the sum of connections so far ; when uname = "Diya": ; given: amanda 2, expect 3 ; given: emmi 0, expect 0 (define (count-user-friendships u total) (+ total (count uname (user-friends u))))) (foldr count-user-friendships 0 sn))) (check-expect (count-friendships "Amanda" SN1) 0) (check-expect (count-friendships "Carlo" SN1) 2) (check-expect (count-friendships "Han" SN1) 5) (check-expect (count-friendships "Suzanne" SN1) 0) ; LIBRARY FUNCTIONS ----------------------------------------------------------- ; drop : String [Listof String] -> [Listof String] ; Remove all occurrences of the given element from the list, if it is present. (define (drop str los) (filter (λ(x) (not (string=? str x))) los)) (check-expect (drop "hi" '()) '()) (check-expect (drop "hello" '("cats" "are not that affectionate")) '("cats" "are not that affectionate")) (check-expect (drop "cats" '("cats" "hi" "i" "still" "love" "cats" "lots")) '("hi" "i" "still" "love" "lots")) ; count : String [Listof String] -> Number ; Count how many times the given string appears in the list. (define (count str los) (foldr (λ(x y) (if (string=? str x) (+ y 1) y)) 0 los)) (check-expect (count "hi" '()) 0) (check-expect (count "hello" '("cats" "are great")) 0) (check-expect (count "cats" '("cats" "hi" "i" "love" "cats" "lots")) 2)