CS151 Labs

Lab 2 will be collected from your subversion repository on Monday, October 10, at 5pm.

Please create a lab 2 directory in your subversion repository with

svn mkdir lab2
Work in the file lab2/lab2.rkt. It is important that this file has exactly this name and location; we will be looking for your work under this name at collection time.

This week, you will practice programming and program design by implementing some common operations on dates.

We present a formula for computing the day of the week (below). The formula only works for the 20th and 21st centuries, so your dates will be restricted to that range.


First write a function leap? to compute whether or not a year is a leap year. Leap years are not simply every fourth year. The precise rule is as follows:

A year is a leap year if it is divisible by 4 and not divisible by 100, or if it is divisible by 400.


Here is a data definition for dates:

;; a date is a
;; (make-date m d y) where
;; - m is a number in [1, 12],
;; - d is a number in [1, 31], and
;; - y is a number in [1900, 2099]
(define-struct date (month day year))

Defining the date structure creates the constructor make-date, which is too permissive: it allows dates like September 31st, or, for that matter, September 32nd. Write the following smart constructor to check the validity of a date before constructing the value.

;; checked-make-date : num num num -> date
In the case of a valid date specification, checked-make-date should return a date. Otherwise, it should raise an error by evaluating the following expression:
(error 'checked-make-date "invalid date")
You can check error cases with check-error (see the documentation).


We now give the formula for computing the days of the week. We first define a "month adjustment" as follows:

MonthAdjustment
10 for leap years, 1 otherwise
23 for leap years, 4 otherwise
34
40
52
65
70
83
96
101
114
126

The day of the week formula is this. Let m, d, and y be the month, day and year of a given date, and let j be the "month adjustment" (per the table above) for the given month and year. Then let n be the following:

n = (y - 1900) + j + d + floor(y/4)
where floor(y/4) is the integer quotient of y divided by 4. (For example, floor(401/4) is 100). Let w be the remainder of n divided by 7. Then if w = 0, the day is Sunday; if w = 1, the day is Monday; ...; if w = 6, the day is Saturday.

Write

;; day-of-week : date -> string
which returns a string ("Sunday", "Monday", etc.)


Don't forget to commit your work! Commit early, commit often.