
		     MASSACHVSETTS INSTITVTE OF TECHNOLOGY
	   Department of Electrical Engineering and Computer Science

	   6.001 -- Structure and Interpretation of Computer Programs
			   Quiz 1   Fall Term   1993
				   Open Book

		  Designing the grading system for the Spring

Print your name at the top of each page of this exam.

Please write clear and concise answers to the questions posed in the spaces
provided in this handout.  You may use scratch paper if you wish, but the spaces
provided for the answers are the ONLY places we will look at when grading the
quiz.  Your answers should be brief and clear.  The staff reserves the right to
ignore illegible answers.  In grading problems that require programming, the
staff will take into consideration the STYLE and clarity of your code, not just
whether it happens to produce the right result.  Before starting, please check
that this booklet has all 8 pages (not counting this cover page).

Note that not all of the problems here involve the full complexity of the
handout.


Print your name here:__ S __ O __ L __ U __ T __ I __ O __ N __ S __


Print your tutor's name here:_______________________________________


Recitation instructor:____________________________________________



If you have any comments about this quiz, please write them here:






Problem 0 (2 points):  What is your tutor's email address?



       Please do not write below this line -- reserved for administrivia.
_______________________________________________________________________________

Problem  Grade   Grader   Prob   Grade   Grader            Grader's Comments
--------------------------------------------------         -----------------
| 0    |   2  |         || 5    |  12  |         |
--------------------------------------------------
| 1    |  12  |         || 6    |  13  |         |
--------------------------------------------------
| 2    |  12  |         || 7    |  12  |         |
--------------------------------------------------
| 3    | 12+1 |         || 8    |  12  |         |
--------------------------------------------------
| 4    |  12  |         ||TOTAL | 99+1 |         |
--------------------------------------------------

Page 1 of 8.        Your Name:__ S __ O __ L __ U __ T __ I __ O __ N __ S __

Problem 1:

The following problem (notes, exercise 1.21) was assigned for tutorial as part
of problem set 3.

Louis Reasoner is having great difficulty testing numbers for primality.  His
FAST-PRIME? test seems to run more slowly than his PRIME? test.  Louis calls his
friend Eva Lu Ator over to help.  When she examines Louis's code, she find that
he has changed the EXPMOD procedure

(define (expmod b e m)
  (cond ((= e 0) 1)
        ((even? e)
         (remainder (square (expmod b (/ e 2) m))
                    m))
        (else
         (remainder (* b (expmod b (- e 1) m))
                    m))))        

to a new version that uses an explicit multiplication, rather than calling
SQUARE:

(define (expmod b e m)
  (cond ((= e 0) 1)
        ((even? e)
         (remainder (* (expmod b (/ e 2) m)
                       (expmod b (/ e 2) m))
                    m))
        (else
         (remainder (* b (expmod b (- e 1) m))
                    m))))

"I don't see what difference that could make," says Louis.  "I do."  says Eva.
"By writing the procedure like that, you have transformed the process from one
that grows as log(n) to one that grows linearly with n."

In the space provided below, write a clear, concise explanation of why Eva is
correct that the first version grows as log(n) while the second grows linearly
with n.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
ANSWER:

	The first version grows as log of the exponent because each
	call either poses a subproblem of half the exponent (if even)
	or a subproblem of one less than the exponent (if odd).  Thus
	if the exponent is odd, after two steps the problem will be
	half because one less than an odd number is an even number.
	(Another way to view the program is that it effectively walks
	down the binary representation of the exponent in bits.  And 
	it takes log(n) bits to represent a number of size n.)

continued next page...

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 



- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

Problem 1 ANSWER continued:

	The second version defeats this strategy by making two
	subproblems, each of size half the exponent, in the even case.
	This builds an exponential tree because each even subproblem
	has two subproblems instead of one.  The exponential tree is
	of height log(exponent) and thus the tree contains O(exponent) 
	subproblems.

12 Points: 
	There were 6 points for observing that the second version
includes two calls to expmod.  The other 6 points were awarded for the
recursive argument to explain the orders of growth.  It was insufficient
to only analyze the first version and not the second.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 


Page 2 of 8.        Your Name:__ S __ O __ L __ U __ T __ I __ O __ N __ S __

Problem 2:
In our implementation of student records, a record is a list of the eight
individual record components.  Suppose instead that we want to group the test
scores into a single substructure.  Our new structure will have the following
partial box-and-pointer diagram:

   ---------   ---------   ---------   ---------   ---------   ---------  
   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |  /|  
-->|   |  ---->|   |  ---->|   |  ---->|   |  ---->|   |  ---->|   | / |  
   | | |   |   | | |   |   | | |   |   | | |   |   | | |   |   | | |/  |  
   --|------   --|------   --|------   --|------   --|------   --|------  
     |           |           |           |           |           |
     V           V           V           V           V           V
   Name         ---------  HW scores   Tutorial    Recitation  Lecture
                |   |   |   
                |   |  ---->Final Score
                | | |   |   
                --|------   
                  |          
                  V          
                 ---------   
                 |   |   |   
                 |   |  ---->Q2 Score
                 | | |   |   
                 --|------   
                   |
                   V
                   Q1 score

In the space provided below, redefine MAKE-STUDENT-RECORD and the selectors
for the record components so that records will now have the above structure.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
ANSWER:

(define (make-student-record name q1 q2 final hw tutorial recitation lecture)
  (list name 
	(cons (cons q1 q2) final)	;; ** only difference
        hw 
	tutorial
	recitation 
	lecture))

(define (student-name record) (list-ref record 0))
(define (q1-score record)    (caar (list-ref record 1)))
(define (q2-score record)    (cdar (list-ref record 1)))
(define (final-score record) (cdr  (list-ref record 1)))
(define (hw-score record)               (list-ref record 2))
(define (tutorial-performance record)   (list-ref record 3))
(define (recitation-performance record) (list-ref record 4))
(define (lecture-attendance record)     (list-ref record 5))

The constructor is suitably changed to produce the box-and-pointer
diagram.  The selectors q1-score, q2-score, and final-score are changed
to access the new structure.  The other selectors must be adjusted to
the appropriate positions in the shorter list.

12 Points:
	The constructor was worth 4 points and each selector was worth
1 point.  You must not violate the abstraction barrier by changing the
arguments to make-student-record.  
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
Page 3 of 8.        Your Name:__ S __ O __ L __ U __ T __ I __ O __ N __ S __

Problem 3:

The procedure COUNT-SATISFIES takes a predicate and a list, and returns the
number of elements in the list that satisfy the predicate.  Here is an
implementation of COUNT-SATISFIES:

(define (count-satisfies pred list)
  (cond ((null? list) 0)
	((pred (car list))
	 (+ 1 (count-satisfies pred (cdr list))))
	(else (count-satisfies pred (cdr list)))))


A.  Does this generate an iterative process or a recursive process? 
    (Circle one.)

		    iterative           recursive

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
ANSWER: recursive (2 points)

	We did give a bonus point for observing that the program
	generates an iterative process if _no_ elements satisfy
	the predicate (ie. if the predicate was (lambda (x) false)).
	Then the program would always recur through the else clause
	and never build up any information.
	
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

B. In the space provided below, write an alternate definition of COUNT-SATISFIES
that evolves the other kind of process.  (I.e., if your answer to (A) was
"iterative" your procedure should evolve a recursive process; if your answer to
(A) was "recursive" your procedure should evolve an iterative process.)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
ANSWER: 

	(define (count-satisfies pred list)
	   (define (iter list count)
	      (cond ((null? list) count)
	            ((pred (car list))  (iter (cdr list) (1+ count)))
	            (else (iter (cdr list) count))))
	   (iter list 0))

5 Points:
	It was insufficient to simply write the procedure named iter
above without including it in another procedure that calls it with an
initial value of 0 for count.  If we call use the above iter procedure
as count-satisfied, then count-satisfies would not be accepting the
right types of arguments (ie. the actual predicate would be passed in
as list and the actual list would be passed in as count).

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

continued next page...

Problem 3 continued:


C.  In the space below, use COUNT-SATISFIES to give an alternate definition of
the procedure NUMBER-OF-TUTORIALS-MISSED from the handout.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
ANSWER: 

	(define (number-of-tutorials-missed record)
	   (count-satisfies
	      (lambda (tutorial-mark)
	         (eq? tutorial-mark 'absent))
	      (tutorial-performance record)))

5 Points:
	The most important part of this problem is to create a
	procedure to pass as the predicate to count-satifies
	that checks if the tutorial mark is absent.  Thus we call
	count-satisfies with this predicate and the list of tutorial
	marks provided by the selector tutorial-performance.  (Note: it
	doesn't matter which version of the selector we use, the
	original or the new one inproblem 2, because of the beauty of
	data abstraction.) 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 


Page 4 of 8.        Your Name:__ S __ O __ L __ U __ T __ I __ O __ N __ S __

Problem 4:

The MIT Narcissism Society, which is looking for new members, has asked us to
send them the names of all 6.001 students who show off in recitation and have
been surly or asleep in tutorial at least three times.  The following procedure
is meant to take a list of student records and return the NAMES (not the records
themselves) of all students that satisfy the required condition:

(define (find-candidates list-of-records)
  (reduce append 
	  '()
	  (map <EXPRESSION-1>
	       list-of-records)))
      
In the space below, write the required <EXPRESSION-1>.  Advice: You can make
good use of the procedure COUNT-SATISFIES from problem 3.


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
ANSWER: 
	The following works for <Expression-1>:

	(lambda (record)
	   (if (and (eq? (recitation-performance record) 'show-off)
	  	    (> (count-satisfies
			  (lambda (tutorial-mark)
			     (or (eq? tutorial-mark 'surly)
				 (eq? tutorial-mark 'asleep)))
			  (tutorial-performance record))
	  	       2))
	       (list (student-name record))
	       '()))

The English specification of this problem is somewhat ambiguous, so we
accepted many solutions.  Ie. if the student was ((surly 3 times) or (asleep
3 times)) vs ((surly or asleep) 3 times).

12 points:
	There were many small parts to this program, but the most
important was to pass a procedure (predicate) to count satisfies (4
points) and return a list of the student's name (2 points) for use with
the (reduce append '() ...) idiom.  Other possible problems that could
cost you 2 points:
	Not having <Expression-1> be a procedure.  (If you used define,
	  but did not indicate what <Expression-1> should be, you
	  lost 1 point.)
	Forgetting the test for 'show-off.
	Incorrect boolean logic.
	Using undefined procedures like asleep?.
	Abstraction violations or wrong selectors.
	Incorrect use of quote.
You could also lose 1 point each for the following problems:
	Thought (recitation-performance record) returned a list.
	No alternative in the if.
	Using the wrong number in the count-satisfies test. 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

Page 5 of 8.        Your Name:__ S __ O __ L __ U __ T __ I __ O __ N __ S __

Problem 5:

Here is the definition of AVERAGE-OF-QUIZZES from the handout:

(define average-of-quizzes
  (weighted-average-individual-methods '(1 1 1)
			               (list q1-score q2-score final-score)))


Suppose instead we had defined it as follows:

(define average-of-quizzes
  (weighted-average-individual-methods '(1 1 1)
			               '(q1-score q2-score final-score)))


A. Will this work?  (Circle one)

			      yes              no

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
ANSWER: no (points: see below)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 


B. Explain your answer to (A) in a couple of sentences.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
ANSWER: 
	The suggested alternative representation produces a list of
	unevaluated symbols rather than the list of procedures that
	weighted-average-individual-methods requires.  If you were to
	try to run the program, at some point there will be an attempt
	to apply one of these symbols as though it were a procedure, and
	the interpreter will complain with an error such as "Application
	of non-procedure object!" 

12 Points for both A & B:
	Amount of credit depended on quality of explanation.  

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

Page 6 of 8.        Your Name:__ S __ O __ L __ U __ T __ I __ O __ N __ S __

Problem 6:

The system in the handout provided no means of combination for
individual-in-team grading methods.  For instance, suppose we have two methods
for grading individuals in teams.  We might want to compute the individual
grades according to both methods, and then assign the better of the two grades.

The following procedure implements this strategy.  It takes two
individual-in-team grading strategies and produces a procedure that, given an
individual and a team, returns the desired value.

(define (best-of strategy1 strategy2)
  (lambda (individual team)
    (let ((istrat1 (strategy1 team))
	  (istrat2 (strategy2 team)))
      (max (istrat1 individual)
	   (istrat2 individual)))))
 
Ben Bitdiddle objects that this way of implementing BEST-OF does not produce a
system that is closed under means of combination.

A.  Explain in a sentence or two what Ben means.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
ANSWER: 
	The problem is that best-of takes two individual-in-team-strategies
	and produces something which is _not_ an individual-in-team-strategy.
	Such a strategy must be of the form: 
		(lambda (team) 
		   ...
		      (lambda (individual)
			 ...))

6 Points:
	You recieved partial credit if you just said that best-of
returns a number.  However, that is not the full story as it is
important that the result of best-of can itself be used as an argument
to best-of, ie. the result must be an individual-in-team-strategy.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 


B.  In the space provided below, give an implementation of BEST-OF that would
answer Ben's objection.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
ANSWER: 
	(define (best-of strategy1 strategy2)
	  (lambda (team)
	    (let ((istrat1 (strategy1 team))
		  (istrat2 (strategy2 team)))
	      (lambda (individual)
		 (max (istrat1 individual)
		      (istrat2 individual))))))

7 Points:
	Partial credit was given for attempting to write something that
returns a procedure rather than a number.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
Page 7 of 8.        Your Name:__ S __ O __ L __ U __ T __ I __ O __ N __ S __

Problem 7:

Here is the definition of MAKE-INDIVIDUAL-IN-TEAM-GRADE from the handout:

(define (make-individual-in-team-grade combiner individual-method team-method)
  (lambda (team)
    (lambda (individual)
      (combiner (individual-method individual)
		(team-method team)))))

Would it be better to rewrite this as:

(define (make-individual-in-team-grade combiner individual-method team-method)
  (lambda (team)
    (let ((g (team-method team)))
      (lambda (individual)
	(combiner (individual-method individual)
		  g)))))

In the space provided below, please explain either why this is a bad idea (e.g.,
it would give wrong results), or why it won't make any difference, or why it's a
good idea.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
ANSWER: 
	The procedures shown return equivalent values for equal
	arguments -- they compute the same function.  Thus both
	are correct.

	The second one is better computationally because it does not
	have to re-compute the team grade for each individual but 
	only computes it once.  This would happen if we called the
	result of make-individual-in-team-grade and gave that a name,
	say foo, and then used foo to grade each person in the team:

		(let ((foo ((make-individual-in-team-grade ... ... ...)
			    team)))
		  (map foo team))
		

12 Points:
	You recieved 6 points for observering the two are logically the
same and 6 points for identifying the performance benifits of the second
version.  

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
Page 8 of 8.        Your Name:__ S __ O __ L __ U __ T __ I __ O __ N __ S __

Problem 8:

Louis Reasoner is interested in devising grading strategies for multiteams.  As
part of exploring these ideas, he needs to write a program MULTITEAM->RECORDS
that returns a list of all student records in a multiteam.  That is to say, if
CLASS is a list of student records and N is an integer, then

  (MULTITEAM->RECORDS (MAKE-MULTITEAM N CLASS))

should return a list of the same elements as in CLASS (although not necessarily
in the same order.)

Louis attempted to define this procedure as follows:

(define (multiteam->records multiteam)
  (reduce
   append
   '()
   multiteam))

A. In the space provided below, give a brief but clear description of why
Louis's procedure doesn't work.  You can illustrate what goes wrong by means of
an example, if you wish.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
ANSWER: 
	The main problem is that this just flattens a list of lists,
	but a multiteam may be deeper than just two levels.  (In other
	words, it is a tree, so we need to compute the fringe.)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

B.  Alyssa P. Hacker remarks that, in order to give a correct definition of
MULTITEAM->RECORDS, one really should have a predicate STUDENT-RECORD? that
tests whether its argument is a student record.  Assume that you have such a
predicate, and complete the following definition of MULTITEAM->RECORDS:

(define (multiteam->records multiteam)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
ANSWER: 
	(define (multiteam->records multiteam)
	   (if (student-record? multiteam)
	       (list multiteam)
	       (reduce append 
		       '()
		       (map multiteam->records multiteam))))

Here we use the predicate student-record? to distinguish teams and
multiteams from individual records (ie. to identify the leaves in our tree
of teams).  We must return a list of the record to work properly with
the (reduce append '() ...) idiom for flattening a list of lists.  In
the general case, we just convert each team in a multiteam recursively by
the use of map and flatten the result.

12 points:
	The most important parts of this problem are returning a list
of the student-record and doing multiteam->records over all the teams in
a multiteam via map.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
