A 1
CS 3 (Clancy) Exam 2
November 4, 1991
Read and fill in this page now.
Do NOT turn the page until you are told to do so.
Your name:
(please printÑlast name, first name)
Your lab section day and time:
Your lab t.a.:
Name of the person sitting to your left:
Name of the person sitting to your right:
Problem 0 Total: /30
Problem 1
Problem 2
Problem 3
Problem 4
Problem 5
This is an open-book test. You have approximately fifty minutes to
complete it. You may consult any books, notes, or other inanimate objects
available to you. To avoid confusion, read the problems carefully. If you find
it hard to understand a problem, ask us to explain it. If you have a question
during the test, please come to the front or the side of the room to ask it.
This exam comprises 15% of the points on which your final grade
will be based. Partial credit will be given for wrong answers.
You are not to use setf within functions. Any other Lisp construct
described in Touretzky chapters 1-8, either part of the ÒDifference Between
DatesÓ case study, the ÒStatisticsÓ case study, the supplementary reading on
applicative operators, or ÒInteger Division and its UsesÓ is ok, though.
Your exam should contain 6 problems (numbered 0 through 5) on 6
pages. Please write your answers in the spaces provided in the test; in
particular, we will not grade anything on the back of an exam page unless
we are clearly told on the front of the page to look there.
RelaxÑthis exam is not worth having heart failure about.
Problem 0 (2 points)
Put your name on each page. Also make sure you have provided the
information requested on the first page.
Problem 1 (6 points)
Fill in the blanks in the function definitions below so that each of the
functions f1 and f2 returns the value 5 when given the list
((january 2) (february 5) (march 4) (april 1) (may 3))
as input. Each blank should be filled with the name of an applicative
operator. There are two answers for function f2; indicate both.
(defun 1-each (x sum) (+ 1 x) )
(defun f1 (L)
( #'1-each (cons 0 L)) )
reduce
(defun f2 (L)
(length ( #'atom L)) )
mapcar
(defun f2 (L)
(length ( #'atom L)) )
remove-if
Problem 2 (3 points)
Indicate the result of evaluating each of the uses of applicative
operators below. If an error results, explain the error.
(defun 1-each (x sum) (+ 1 x))
(defun add1 (x) (+ 1 x))
(defun 1-element? (L) (= (length L) 1))
(defun sum-to-5? (x y) (= (+ x y) 5))
(reduce #'1-each '(2 4 6))
4
(reduce #'add1 '(1 4 6))
wrong number of inputs to add1
(remove-if-not #'sum-to-5? '((1 2) (2 3) (3 4)))
wrong number of inputs to sum-to-5?
Problem 3 (4 points)
Given below is the code for the min and list-min functions from
Appendix A of the ÒStatisticsÓ case study.
; Return the smaller of two numeric values.
(defun min (x y)
(if (< x y) x y) )
; Return the smallest value in the list L.
(defun list-min (L)
(reduce #'min L) )
Suppose, when typing in the code for the min function, you
mistakenly typed an x for a y in the if condition in min, so that min was
defined as
(defun min (x y) ; incorrect version
(if (< x x) x y) )
Part a
Give an example of a list of at least three elements, for which list-
min using the incorrect version of min produces the same output as list-
min using the correct version of min.
Part b
Describe, as completely as possible, the collection of lists for which
list-min using the incorrect version of min produces the same output as
list-min using the correct version of min. Your answer is a description of
test cases that would fail to reveal the bug in the mistyped min function.
those for which the min is the last thing in the
list
Problem 4 (7 points)
The difference in days between two dates in 1991 can be computed
recursively, with the aid of two functions date-before and date-after.
Date-before takes a date as input, and returns the date immediately
before; similarly, date-after returns the date immediately after its input.
Some examples:
expression value returned
(date-before '(january 5)) (january 4)
(date-before '(december 1)) (november 30)
(date-after '(january 31)) (february 1)
Part a
Complete the definition of the recursive version of days-between
below, by filling in the base case(s).
; Return the difference in days between date1 and date2.
; The two dates themselves are included in the difference.
; date1 and date2 both represent dates in 1990,
; with date1 being the earlier of the two.
(defun days-between (date1 date2)
(cond
((equal date1 date2) 1)
((equal date1 (date-before date2)) 2)
(T (+ 2 (days-between (date-after date1)
(date-before date2) ))) ) )
Part b
Using only the date-before and equal functions (with if or cond),
write another recursive version of days-between.
; Return the difference in days between date1 and date2.
; The two dates themselves are included in the difference.
; date1 and date2 both represent dates in 1990,
; with date1 being the earlier of the two.
(defun days-between (date1 date2)
(if (equal date1 date2) 1
(+ 1 (days-between date1 (date-before date2))) )
)
Problem 5 (8 points)
Suppose that a table season-table, which associates the date on
which each season begins with the name of that season, has been set up as
follows.
(setf season-table
'(((january 1) winter) ((march 31) spring)
((june 21) summer) ((september 21) autumn)
((december 21) winter) ) )
Suppose also that a function same-or-earlier? has been written that takes
two 1991 dates as inputs, and returns true when the first date is the same
as or comes before the second and false when the first date comes after the
second. Some examples:
expression value returned
(same-or-earlier? '(may 5) '(may 5)) true
(same-or-earlier? '(may 5) '(june 21)) true
(same-or-earlier? '(may 5) '(january 30)) false
Part a
Use same-or-earlier?, season-table, reverse, and find-if to
write a function season that takes a date as input and returns the name of
the season that contains the date. Some examples:
expression value to return
(season '(january 5)) winter
(season '(june 20)) spring
(season '(june 21)) summer
(season '(december 25)) winter
Write your function in the space below. If you need an auxiliary
function, you may use either defun or lambda to provide it.
(defun season (date)
(second (find-if
#'(lambda (x)
(same-or-earlier? (first x) date))
(reverse season-table) ))
)
Part b
Why could you not use assoc with reverse and season-table to
write the season function?
assoc uses a test for equality, and only works with
atomic keys