Problem Set 3


home work!

Programming Language BSL

Purpose The purpose of this problem set is to internalize design skills. Topically, the problem set focuses on functions that process structures, arbitrary unions of data, and simple recursive types.

Finger Exercises HtDP/2e: 65, 67, 68, 69, 70, 71, 77, 78, 79, 86, 94, 102, 104


Problem 1 Consider the following structure definitions:
(define-struct room (building number window?))
(define-struct office-hours (time location))
(define-struct professor (name office-hours))

  1. Provide data definitions for the structure definitions above. Make appropriate assumptions about what data types go with which field and how the data types relate to each other.

  2. What are the names of the constructors, selectors, and predicates that each of the structures add to the environment and what are their signatures?

  3. Develop templates for functions that consume the structures above. Don’t forget a signature.


Problem 2 Here is a data definition for measuring time:
; A TimePeriod is one of:
; - "am"
; - "pm"
; interpretation: represents whether the time on a 12-hour clock is
; before midday ("am") or at/after midday ("pm")
(define-struct time (hours minutes am/pm))
; A Time is a structure:
;    (make-time Number Number TimePeriod)
; interpretation: expresses time in hours, minutes, and whether or not it is pre-midday
; Constraints:
;  hours is always between 0 and 11
;  minutes is always between 0 and 59

  1. Design the templates for TimePeriod and Time.

  2. Design the function tock, which adds one minute to the given Time.

  3. Design the function time->text, which converts a time to a text. The text should look like the display of a common alarm clock, i.e., it should separate the minutes from the hours with a colon, followed by "AM" or "PM". Hint: text cannot take numbers as input. What other function will you need?

  4. After you have developed these functions, add a main function, which launches a big-bang program at a given time and runs until the clock displays "11:59PM".


Problem 3 So far you have written examples like (circle 50 "solid" "red") or (square 30 "outline" "blue"), or even functions like magic-wand that draw more complicated pictures. In this problem, you’re going to build a big-bang program that lets the user of your program type in a number and a color, and will draw a solid circle of that size and color. This is a long and tricky problem, so get started early!

Big-bang handles keystrokes one-at-a-time using the function you specify to on-key, which means you will have to somehow store up the user’s keystrokes in your world, until you’re ready to display the result. (Look in the documentation at the signature for the function you specify: it takes the current world state—whatever that is!—and a KeyEvent, and produces a new world state.)

Succeeding in this problem will depend on your adherance to the design recipe, especially in the formulation of your data definition. Be sure to test every part of your program: many things all have to work, one after another, in order for this program to succeed. Without tests, it will be practically impossible for you to debug why it isn’t working. Additionally, tests help the TAs and tutors understand what you think is happening in your program, and they will be rather unsympathetic if they have to decipher what you’ve written without any tests to guide them!

Here are some strong hints on how to structure this program:
  • ; A World is one of
    ; - A NumberWorld (when the user is entering digits of the size)
    ; - A ColorWorld (when the user is entering the color)
    ; - A FinalWorld (when the user is done entering everything)
  • A NumberWorld needs to keep track of the number that’s been entered so far. If the user presses a digit, you should update that number. (Hint: You may want to look at string->number, string>=? and string<=?, as helpers for this. Also: (string<=? "0" "9") is true. How might those facts all be relevant?) If the user presses the enter key, the number is finished and the world should become a ColorWorld. If the user presses any other key, ignore it. Design a function next-number-world that takes a NumberWorld and a key, and produces the appropriate next World.

  • While the user is entering digits, the world should be drawn as

    image

    Design a function number-world->image that draws this.

  • A ColorWorld needs to keep track of the color name that’s been entered so far...and also the number that had been entered already. If the user presses any lowercase alphabetical key, you should update the color. (Hint: You may want to look again at string>=? and string<=? as helpers for this.). If the user presses the enter key, the color is finished and the world should become a FinalWorld. If the user presses any other key, ignore it. Design a function next-color-world that takes a ColorWorld and a key, and produces the appropriate next World.

  • While the user is entering the color, the world should be drawn as

    image

    Design a function color-world->image that draws this.

  • A FinalWorld needs to keep track of the final number and the final color name. A FinalWorld should draw a circle of the given color and size (shown here for 25 and "blue"):

    image

    If the user enters a color name that Racket doesn’t know, it will just draw in black, so you don’t have to do any fancy error checking for invalid colors.

    Design a function final-world->image that draws this.

  • You will need to define a function world->image for Worlds, and a handle-key function as well: you will give these to big-bang in the to-draw and on-key arguments, respectively. Think very carefully about the template for Worlds, and design these two functions. If you’ve done the earlier parts of the problem correctly, these should be very short!

  • You should stop your big-bang program when the final world is reached. To do this, add (stop-when final-world? final-world->image) to your big-bang call: it says to stop when the world becomes a FinalWorld, and will draw that final world using final-world->image.

Good luck!


Note: The following problem deals with recursive data. You will not learn this until later this week in class, and as such the problem is not long. Feel free to read the problem, but please do not attempt it until it is covered in class, unless you and your partner have read about in the book and also understand it.

Problem 4 In class we talked about nested Russian matryoshka dolls. Here, we’re going to enhance that data definition a bit, by elaborating each doll with a size:

; A SizedMD (sized matryoshka doll) is one of:
; - 'solid
; - (make-md Number SizedMD)
(define-struct md (size nested))
  1. Write the template for a SizedMD.

  2. This used to suggest bigger-than. That was a mistake!

    Design a function smaller-than that takes a SizedMD and a Number n and determines if the given doll’s size is less than n. Assume that a 'solid SizedMD has size 0.

  3. Design a function will-they-all-fit? that takes a single SizedMD determines whether or not that given doll is large enough to contain all dolls nested inside it (i.e., is it bigger than they are), and whether they in turn are large enough to contain any dolls nested inside them, etc. Again, assume that any 'solid dolls have size 0.