Many American holidays are celebrated on a fixed day of the week, in a week beginning on a specified day. For instance:
Thanksgiving Day is the fourth Thursday in November, that is, Thursday of the week beginning on November 22.
Labor Day is the first Monday in September, that is, Monday of the week beginning on September 1.
Election Day is the first Tuesday after the first Monday in November, that is, Tuesday of the week beginning on November 2.
Identifying a holiday in this way makes it easy to determine its date in a given year if you are looking at a calendar for that year, with the days arranged in weeks. If you don't have such a calendar for the given year, however, working out the date of the holiday can be a difficult and error-prone task. This makes it suitable for automation.
Write and test a Scheme procedure that takes the number of a year as its argument and returns the date of Thanksgiving Day in that year. A date can be expressed as a list of three integers, the first giving the number of the year, the second the number of the month within the year, and the third the number of the day within the month. For instance, (1998 11 26) represents November 26, 1998 -- the date of Thanksgiving Day this year. When your procedure is called with the argument 1998, it should return this three-element list.
In order to carry out this computation accurately, you'll need to know exactly when leap years occur in the calendar used in America (the Gregorian calendar). The exact rule is that a year is a leap year if its number is (1) divisible by 400, or (2) divisible by 4 but not by 100. So 1996 was a leap year (under clause 2), and 2000 will be a leap year (under clause 1); but 1998 is not a leap year, and neither was 1900.
Since the Gregorian calendar was adopted in America in 1752, you may assume
that only years whose numbers are greater than or equal to 1752 will be
given as arguments (and your procedure may call error if this
precondition is not met).
Adapting the procedure you wrote for part A, write and test a Scheme procedure that takes the number of a year as its argument and returns both the date on which Daylight Savings Time begins in that year (Sunday of the week beginning April 1) and the date on which it ends (Sunday of the week beginning October 25).
Generalizing the code you wrote for parts A and B, write and test a Scheme
procedure that takes two arguments, a day of the week (represented by one
of the symbols Sunday, Monday,
Tuesday, Wednesday, Thursday,
Friday, and Saturday) and a date (represented by
a three-element list) and returns the date of the specified day in the week
beginning on the specified date. (So, for instance, calling this procedure
with the arguments Friday and (1998 3 16) should
yield (1998 3 20), because March 20, 1998, is the Friday of
the week beginning on March 16, 1998.)
Test this procedure carefully -- there are more special cases than you might initially suppose. You may want to work up a list of test cases even before you write the procedure.
This document is available on the World Wide Web as
http://www.math.grin.edu/courses/Scheme/spring-1998/exercise-5.html
created February 26, 1998
last revised June 21, 1998