Homework 7
Due Date: Friday March 12, 9pm
Purpose To practice using list abstractions
Expectations
This is a pair assignment. Remember that working in pairs means that you both work on the problems together, ideally by one person developing the solution, while the other person observes and comments. After a while, you switch roles. Working in pairs does not mean to divvy up the work between the two of you.
As with all assignments, you must upload one .rkt file (for the entire pair/team), in the language specified at the top of the assignment to the Handin Server. For this assignment, you must use ISL. Using the wrong language will invalidate your submission and result in a score of 0, so please be careful.
Unless otherwise stated, all data and functions you design must be designed according to the data and function design recipes, resp., following all four steps in each case.
Your code MUST conform to the guidelines outlined in the style guide on the course website. The style guide will be updated as the semester progresses so please remember to read it before submitting each assignment.
-----------------------------------------------------------------------------
This assignment focuses on applications of list abstractions. Each exercise will involve using one or more list abstractions in some combination. They might require writing additional helper functions: you should apply the usual design recipe for each of those. Points will be deducted if you did not use list abstractions where it would have clearly made the code more concise.
Another important note: unless explicitly allowed for some particular exercise (none in this homework), you are not allowed to use the functions equal?, member?, or remove. These all use equal? internally, which has some strange properties we need to avoid.
Exercise 1 Reimplement the function hexstr->num from HW6 using list abstractions. Assume the data type HexChar is already defined for you, and that you have the functions hexchar? and hexchar->num written. You are also allowed to use the built-ins explode and reverse.
Recall: hexstr->num converts a string of hexadecimal characters to its numerical equivalent. For example, if the input is "1F2", it would return 498 (1 * 162 + 15 * 16 + 2). It should also handle errors the exact same way as before: if the input string has any characters other than the 16 legal hexadecimal values, it should return -1.
We suggest using the same basic algorithm outlined in HW6: Convert the input string into a list of individual characters. Then process the list of 1String into a composite cumulative numerical value. Use the functions hexchar? and hexchar->num to help you, but of course in a list abstract-y style. We are providing some cryptic implementations for you to use if you don’t want to use your implementations from HW6. (We’ve made them a little strange so that they won’t interfere with HW6 if you are still working on that. You don’t need to figure out how they work. In fact, you should ignore the code of these functions.)
(define (hexchar? hc) (let ((hcc (string-ref hc 0))) (or (and (char>=? hcc #\0) (char<=? hcc #\9)) (and (char>=? hcc #\A) (char<=? hcc #\F))))) (define (hexchar->num hc) (let ((hcc (string-ref hc 0))) (if (char>=? hcc #\A) (+ 10 (- (char->integer hcc) (char->integer #\A))) (- (char->integer hcc) (char->integer #\0))))) HINT: The comment in HW6 about reversing the string might still be useful, but you might also want to consider what the difference between foldr and foldl implies.
For the remaining exercises, refer to the following data definition used to represent a community of users on an online neighborhood community website:
(define-struct user [username friends rating]) (define-struct proctor [username friends community rank]) ; A SiteMember is one of: ; - (make-user String [List-of String] NatNum) ; - (make-proctor String [List-of String] String NatNum) ; and represents either: ; - a regular user's login username, friends' usernames, and community rating ; - a site supervisor's login user name, friends' usernames, community they manage, ; and their supervisory rank (define SM-USER-1 (make-user "fundies1" (list "jo6n") 2)) (define SM-USER-2 (make-user "jo6n" (list "fundies1" "adam12") 4)) (define SM-PROCTOR-1 (make-proctor "agent86" (list "adam12" "agent99") "Control Agents" 99)) (define SM-PROCTOR-2 (make-proctor "adam12" (list "agent86" "fundies1") "CHIPs" 12)) ; sitemember-temp : SiteMember -> ? (define (sitemember-temp sm) (... (cond [(user? sm) (... (user-username sm) (los-temp (user-friends sm)) (user-rating sm) ...)] [(proctor? sm) (... (proctor-username sm) (los-temp (proctor-friends sm)) (proctor-community sm) (proctor-rank sm) ...)])))
Exercise 2 Design the function only-proctors that accepts a list of site members, and produces a list of only the proctors.
Exercise 3 Design the function all-friends that returns a single list of all of the friends mentioned by anyone in the list of site members. You do not need to remove duplicates, if any exist.
Exercise 4 Design the function num-users that counts the number of regular users (not proctors) in a list of site members.
Exercise 5 Design the function popular? that determines if at least one person in a site member list has more than one friend.
Exercise 6 Design the function most-popular that computes for a list of site members the number of friends the member with the most friends has.
Exercise 7 Design the function highest-rating that computes for a list of site members the rating of the user with the highest rating.
Exercise 8 Design the function bogus-friends that creates a list of all usernames declared as friends by any member in a list of site members, who do not have a record in the list.
For this exercise only, you are allowed to write helper functions based on the standard list template; in fact, you will have to: think about why certain functions seem to be impossible to write using list abstractions. We had such a case in the lecture as well.
Also, a reminder that you are not still allowed to use the remove function.