about summary refs log tree commit diff stats
path: root/js/games/nluqo.github.io/~bh/61a-pages/Volume2
diff options
context:
space:
mode:
authorelioat <elioat@tilde.institute>2023-08-23 07:52:19 -0400
committerelioat <elioat@tilde.institute>2023-08-23 07:52:19 -0400
commit562a9a52d599d9a05f871404050968a5fd282640 (patch)
tree7d3305c1252c043bfe246ccc7deff0056aa6b5ab /js/games/nluqo.github.io/~bh/61a-pages/Volume2
parent5d012c6c011a9dedf7d0a098e456206244eb5a0f (diff)
downloadtour-562a9a52d599d9a05f871404050968a5fd282640.tar.gz
*
Diffstat (limited to 'js/games/nluqo.github.io/~bh/61a-pages/Volume2')
-rw-r--r--js/games/nluqo.github.io/~bh/61a-pages/Volume2/CS 61A Course Reader, Volume 2.html154
-rw-r--r--js/games/nluqo.github.io/~bh/61a-pages/Volume2/Final/f-1.pdfbin0 -> 64434 bytes
-rw-r--r--js/games/nluqo.github.io/~bh/61a-pages/Volume2/Final/f-2.pdfbin0 -> 36255 bytes
-rw-r--r--js/games/nluqo.github.io/~bh/61a-pages/Volume2/Final/f-2.soln.txt540
-rw-r--r--js/games/nluqo.github.io/~bh/61a-pages/Volume2/Final/f-3.soln.txt1125
-rw-r--r--js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm1/mt1-1.soln.txt423
-rw-r--r--js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm1/mt1-2.pdfbin0 -> 35908 bytes
-rw-r--r--js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm1/mt1-3.pdfbin0 -> 53024 bytes
-rw-r--r--js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm2/mt2-1.pdfbin0 -> 34170 bytes
-rw-r--r--js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm2/mt2-1.soln.txt411
-rw-r--r--js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm2/mt2-2.soln.txt609
-rw-r--r--js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm2/mt2-3.pdfbin0 -> 38094 bytes
-rw-r--r--js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm3/mt3-1.pdfbin0 -> 142270 bytes
-rw-r--r--js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm3/mt3-1.soln.txt526
-rw-r--r--js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm3/mt3-2.soln.txt484
-rw-r--r--js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm3/mt3-3.soln.txt459
-rw-r--r--js/games/nluqo.github.io/~bh/61a-pages/Volume2/OOP/belowline.pdfbin0 -> 74088 bytes
-rw-r--r--js/games/nluqo.github.io/~bh/61a-pages/Volume2/OOP/ref-man.pdfbin0 -> 63994 bytes
-rw-r--r--js/games/nluqo.github.io/~bh/61a-pages/Volume2/Therac-25.pdfbin0 -> 4792426 bytes
-rw-r--r--js/games/nluqo.github.io/~bh/61a-pages/Volume2/mapreduce-osdi04.pdfbin0 -> 190711 bytes
-rw-r--r--js/games/nluqo.github.io/~bh/61a-pages/Volume2/quick.pdfbin0 -> 69924 bytes
-rw-r--r--js/games/nluqo.github.io/~bh/61a-pages/Volume2/r5rs.pdfbin0 -> 494729 bytes
-rw-r--r--js/games/nluqo.github.io/~bh/61a-pages/Volume2/sicp-errata.txt56
-rw-r--r--js/games/nluqo.github.io/~bh/61a-pages/Volume2/word.txt121
24 files changed, 4908 insertions, 0 deletions
diff --git a/js/games/nluqo.github.io/~bh/61a-pages/Volume2/CS 61A Course Reader, Volume 2.html b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/CS 61A Course Reader, Volume 2.html
new file mode 100644
index 0000000..56f5a05
--- /dev/null
+++ b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/CS 61A Course Reader, Volume 2.html
@@ -0,0 +1,154 @@
+<html><head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8"><title>CS 61A Course Reader, Volume 2</title><style type="text/css">@namespace url(http://www.w3.org/1999/xhtml);
+@font-face {
+  font-family: 'EasyRead2';
+  font-style: normal;
+  font-weight: 400;
+  src: local('EasyRead2'), url(https://cdn.rawgit.com/PullJosh/files/gh-pages/Arial-LargePeriod2.woff) format('woff');
+}input[type="text"], input[type="textarea"], textarea {
+    font-family: "EasyRead2" !important;
+  }</style></head>
+<body>
+ 
+<center>
+<h1> CS61A: Structure and Interpretation of Computer Programs </h1>
+<h3> Course Reader, Volume 2: Reference Documents </h3>
+</center>
+
+<p><b>These documents are here for online reference!  Please do not print
+these on the printers in Berkeley computer labs.  Lab printers are for your
+homework and project solutions, not for reference documents.  Thank you.</b>
+
+</p><p>For many years I resisted the trend to putting course materials online,
+but I've been convinced because of the increasing numbers of people who
+aren't at Berkeley but use the
+<a href="http://wla.berkeley.edu/main.php?course=cs61a">online lectures</a>
+to study SICP.  Welcome, visitors!
+
+</p><ul>
+<li><a href="https://people.eecs.berkeley.edu/~bh/61a-pages/Volume2/OOP/aboveline.pdf">
+Object-Oriented Programming: Above the Line View</a>
+</li><li>&nbsp;&nbsp;&nbsp;<a href="OOP/ref-man.pdf">
+Reference Manual for the OOP Language</a>
+</li><li><a href="OOP/belowline.pdf">
+Object-Oriented Programming: Below the Line View</a>
+</li><li><a href="https://people.eecs.berkeley.edu/~bh/61a-pages/Volume2/gnuemacs.pdf">
+Highlights of GNU Emacs</a><sup>*</sup>
+</li><li>&nbsp;&nbsp;&nbsp;<a href="quick.pdf">
+Emacs Quick Reference Guide</a><sup>*</sup>
+</li><li><a href="https://people.eecs.berkeley.edu/~bh/61a-pages/Volume2/exit.pdf">
+Exit Information (Read at end of semester!)</a>
+</li><li><a href="Therac-25.pdf">
+An Investigation of the Therac-25 Accidents</a><sup>**</sup>
+</li><li><a href="r5rs.pdf">
+Revised<sup>5</sup> Report on Scheme</a><sup>***</sup><br />
+(the last <i>real</i> version of Scheme before its hostile takeover
+by industrial programmers)
+</li><li><a href="mapreduce-osdi04.pdf">
+MapReduce: Simplified Data Processing on Large Clusters</a><sup>****</sup>
+</li><li>Sample Exams:
+<ul>
+<li><b>Please read this:</b>
+
+<p>These exams are made up of actual past exam questions, but reorganized to
+make each sample more comprehensive and to choose the best possible questions.
+Some of the exams are a little longer (by one question) than actual exams, but
+they're in the right ballpark.
+
+</p><p>Since the questions within a sample are taken from different semesters,
+don't try to compare the number of points between problems. The solutions
+include scoring information only to give you an idea of how part credit is
+awarded within each problem.
+
+</p></li><li>Midterm 1
+<ul>
+<li><a href="https://people.eecs.berkeley.edu/~bh/61a-pages/Volume2/Midterm1/mt1-1.pdf">
+Sample exam 1</a>
+</li><li><a href="Midterm1/mt1-1.soln.txt">
+Solutions to sample exam 1</a>
+</li><li><a href="Midterm1/mt1-2.pdf">
+Sample exam 2</a>
+</li><li><a href="https://people.eecs.berkeley.edu/~bh/61a-pages/Volume2/Midterm1/mt1-2.soln.txt">
+Solutions to sample exam 2</a>
+</li><li><a href="Midterm1/mt1-3.pdf">
+Sample exam 3</a>
+</li><li><a href="https://people.eecs.berkeley.edu/~bh/61a-pages/Volume2/Midterm1/mt1-3.soln.txt">
+Solutions to sample exam 3</a>
+</li></ul>
+</li><li>Midterm 2
+<ul>
+<li><a href="Midterm2/mt2-1.pdf">
+Sample exam 1</a>
+</li><li><a href="Midterm2/mt2-1.soln.txt">
+Solutions to sample exam 1</a>
+</li><li><a href="https://people.eecs.berkeley.edu/~bh/61a-pages/Volume2/Midterm2/mt2-2.pdf">
+Sample exam 2</a>
+</li><li><a href="Midterm2/mt2-2.soln.txt">
+Solutions to sample exam 2</a>
+</li><li><a href="Midterm2/mt2-3.pdf">
+Sample exam 3</a>
+</li><li><a href="https://people.eecs.berkeley.edu/~bh/61a-pages/Volume2/Midterm2/mt2-3.soln.txt">
+Solutions to sample exam 3</a>
+</li></ul>
+</li><li>Midterm 3
+<ul>
+<li><a href="Midterm3/mt3-1.pdf">
+Sample exam 1</a>
+</li><li><a href="Midterm3/mt3-1.soln.txt">
+Solutions to sample exam 1</a>
+</li><li><a href="https://people.eecs.berkeley.edu/~bh/61a-pages/Volume2/Midterm3/mt3-2.pdf">
+Sample exam 2</a>
+</li><li><a href="Midterm3/mt3-2.soln.txt">
+Solutions to sample exam 2</a>
+</li><li><a href="https://people.eecs.berkeley.edu/~bh/61a-pages/Volume2/Midterm3/mt3-3.pdf">
+Sample exam 3</a>
+</li><li><a href="Midterm3/mt3-3.soln.txt">
+Solutions to sample exam 3</a>
+</li></ul>
+</li><li>Final exam
+<ul>
+<li><a href="Final/f-1.pdf">
+Sample exam 1</a>
+</li><li><a href="https://people.eecs.berkeley.edu/~bh/61a-pages/Volume2/Final/f-1.soln.txt">
+Solutions to sample exam 1</a>
+</li><li><a href="Final/f-2.pdf">
+Sample exam 2</a>
+</li><li><a href="Final/f-2.soln.txt">
+Solutions to sample exam 2</a>
+</li><li><a href="https://people.eecs.berkeley.edu/~bh/61a-pages/Volume2/Final/f-3.pdf">
+Sample exam 3</a>
+</li><li><a href="Final/f-3.soln.txt">
+Solutions to sample exam 3</a>
+</li></ul>
+</li></ul>
+</li><li><a href="mapreduce-osdi04.pdf">
+Mapreduce: Simplified Data Processing on Large Clusters</a><sup>****</sup>
+</li><li><a href="https://people.eecs.berkeley.edu/~bh/61a-pages/Volume2/notes.pdf">
+Lecture Notes</a>
+</li><li><a href="sicp-errata.txt">
+SICP Errata</a><sup>*****</sup>
+</li><li><a href="word.txt">
+Berkeley Word/Sentence Functions</a>
+</li><li>Ergonomic Information (external links):
+<ul>
+<li><a href="https://www.uhs.umich.edu/computerergonomics">
+Computer Workstation Ergonomics (UMich)</a>
+</li><li><a href="https://www.ors.od.nih.gov/sr/dohs/HealthAndWellness/Ergonomics/Pages/ergonomics_home.aspx">
+Ergonomics (NIH DOHS)</a>
+</li></ul>
+</li></ul>
+
+<p>
+*: Prof. Paul Hilfinger, UCB EECS<br>
+**: Nancy G. Leveson, Clark S. Turner. IEEE <cite>Computer</cite>, July 1993<br>
+***: Richard Kelsey, William Clinger, Jonathan Rees (Editors), et al., 1998<br>
+****: Jeffrey Dean, Sanjay Ghemawat, Google, Inc., OSDI 2004<br>
+*****: Harold Abelson, Gerald Jay Sussman, Julie Sussman, 1999
+</p><p>&nbsp;
+</p><p>&nbsp;
+</p><p>&nbsp;
+</p><p><a href="../Volume1/CS&#32;61A&#32;Course&#32;Reader,&#32;Volume&#32;1.html">Volume 1</a>
+</p><p><a href="../../61a-pages">Back to class web page</a>
+
+
+</p></body></html>
diff --git a/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Final/f-1.pdf b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Final/f-1.pdf
new file mode 100644
index 0000000..65ea079
--- /dev/null
+++ b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Final/f-1.pdf
Binary files differdiff --git a/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Final/f-2.pdf b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Final/f-2.pdf
new file mode 100644
index 0000000..d5d8ddb
--- /dev/null
+++ b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Final/f-2.pdf
Binary files differdiff --git a/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Final/f-2.soln.txt b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Final/f-2.soln.txt
new file mode 100644
index 0000000..4f1a8a1
--- /dev/null
+++ b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Final/f-2.soln.txt
@@ -0,0 +1,540 @@
+CS 61A		Solutions to sample final exam #2
+
+1.  HOFs in 21 project
+
+A higher order procedure is one that uses procedures as data -- either as
+arguments or as its return value.  Many people forgot about the latter.
+
+BEST-TOTAL takes a hand (a sentence) as argument and returns a number.
+No procedures; not higher order.
+
+STOP-AT-17 takes a hand (a sentence) and a card (a word) as arguments,
+returning #T or #F.  No procedures; not higher order.
+
+PLAY-N takes a strategy (which is a procedure!) and a number as arguments,
+returning a score.  It's higher order.
+
+STOP-AT takes a number as argument, returning a strategy -- a procedure.
+So it's higher order.
+
+MAJORITY takes three strategies as arguments and returns a strategy.
+Clearly higher order!
+
+
+Scoring: 2 points if correct; 1 point if all but one correct (usually
+leaving out STOP-AT).
+
+
+2.  Foo and baz.
+
+(foo 3) ==> (if 3 (foo #f) 5)
+        ==> (foo #f)
+        ==> (if #f (foo #f) 5)
+        ==> 5
+
+(baz 3) ==> (and 3 (baz #f) 5)
+        ==> (and (baz #f) 5)       ; since 3 is true
+        ==> (and (and #f (baz #f) 5) 5)
+        ==> (and #f 5)             ; inner AND is false
+        ==> #f
+
+Scoring: 1 point each.
+
+
+3.  Iterative and recursive.
+
+FOO is iterative; BAZ is recursive.
+
+In FOO, when IF decides to evaluate (foo #f), it already knows that whatever
+the answer from (foo #f) is will be the answer to the entire problem.
+
+In BAZ, after the (baz #f) returns, AND must check whether the answer is
+true or false.  If false (as, in fact, it is), then indeed the answer to
+(baz #f) is also the answer to (baz 3).  But AND didn't know that until the
+recursive call is complete!  If (baz #f) had been true, the answer would
+have been 5.
+
+A good one-sentence answer:  "An iterative process is one in which
+the caller has no more work to do once the recursive callee returns."
+
+Many people quoted sentences from the book, often the one about "deferred
+operations"; we accepted these if it sounded as if you might have some idea
+what it actually meant.
+
+Some people quoted a sentence about how something "depends on the return
+value" but mostly these answers were wrong: the answer to the overall
+problem does depend, in both cases, on the answer to the recursive call.
+The question is whether it also depends on anything else!
+
+Worst of all was "FOO is iterative because IF is a special form."
+Sorry -- AND is a special form, too!
+
+Scoring: 2 points if you had FOO iterative and BAZ recursive, with a
+convincing sentence.  1 point if you had FOO iterative and BAZ recursive.
+(If you had FOO recursive and/or BAZ iterative, we didn't even read your
+sentence.)
+
+
+4.  How are the pairs connected?
+
+We know that A's box and pointer diagram looks like this:
+
+A --> [1 . -]---> [2 . -]---> [ | . -]---> [6 . /]
+                                |
+                                V
+                               [3 . -]---> [4 . -]---> [5 . /]
+
+We also know that (CDDR B) is the same pair as (CADDR A), which is the pair
+whose car is 3.  Therefore the list (3 4 5) is shared between A and B, so
+the diagram is
+
+A --> [1 . -]---> [2 . -]---> [ | . -]---> [6 . /]
+                                |
+                                V
+ B --> [1 . -]---> [2 . -]---> [3 . -]---> [4 . -]---> [5 . /]
+
+We also know that (CADDR C) is *not* the same pair as (CADDR A), so the list
+C must have its own distinct pair with 3 in the car.  On the other hand,
+(CDADDR C) *is* the same as (CDDDR B), so the pairs with 4 and 5 in the cars
+are shared between C and the other lists:
+
+A --> [1 . -]---> [2 . -]---> [ | . -]---> [6 . /]
+                                |
+                                V
+ B --> [1 . -]---> [2 . -]---> [3 . -]---> [4 . -]---> [5 . /]
+                                          ^
+                                         /
+                               [3 . -]--/
+                                ^
+                                |
+C --> [1 . -]---> [2 . -]---> [ | . -]---> [6 . /]
+
+(Actually, we don't know whether or not A and C share the pair whose car is
+6.  But this will turn out not to affect the solution.)
+
+Now we make two changes to the box and pointer diagram, changing one of the
+threes to a seven, and changing the four to an eight:
+
+A --> [1 . -]---> [2 . -]---> [ | . -]---> [6 . /]
+                                |
+                                V
+ B --> [1 . -]---> [2 . -]---> [7 . -]---> [8 . -]---> [5 . /]
+                                          ^
+                                         /
+                               [3 . -]--/
+                                ^
+                                |
+C --> [1 . -]---> [2 . -]---> [ | . -]---> [6 . /]
+
+We can read the results directly from the diagram:
+
+B is (1 2 7 8 5)
+C is (1 2 (3 8 5) 6)
+
+Scoring: 1 point each.
+
+
+5.  OOP to normal Scheme
+
+(define (make-echo saved)
+  (let ((count 0))
+    (lambda (message)
+      (cond ((eq? message 'count) count)
+	    ((eq? message 'saved) saved)
+	    (else (set! count (+ count 1))
+		  (let ((result saved))
+		    (set! saved message)
+		    result))))))
+
+The code for the ELSE clause is exactly the code for the default-method
+in the OOP class definition!  We didn't understand why so many people
+invented much more complicated ways to do it -- or, worse, incorrect ways.
+
+Scoring:
+3  correct
+2  has the idea (at least a dispatch procedure inside the let)
+1  has an idea
+0  other
+
+Most people did okay on this, but a fairly frequent one-point answer had the
+LET (for COUNT) inside the LAMBDA instead of outside.  This means you missed
+the whole idea about local state variables.
+
+A noteworthy zero-point solution tried to avoid the problem that the inner
+LET solves this way:
+
+           (else (set! count (+ count 1))
+                 (display saved)               ; wrong wrong wrong!
+		 (set! saved message))
+
+By now everyone should understand that procedures return values, and that
+printing isn't the same as returning, because it doesn't allow for
+composition of functions, the most important programming technique you will
+ever learn.
+
+
+6.  mystery stream
+
+The stream is made by sticking a 1 in front of an interleave of the integers
+with something:
+
+1   1 ___ 2 ___ 3 ___ 4 ___ 5 ___ 6 ___ 7 ___ 8 ___ 9 ___ 10
+
+Then you just fill in the blanks with the elements of MYSTERY, including all
+of them -- the initial 1, the integers, and the underlined ones:
+
+1   1 _1_ 2 _1_ 3 _1_ 4 _2_ 5 _1_ 6 _3_ 7 _1_ 8 _4_ 9 _2_ 10
+
+
+Scoring: 3 points for the above solution.  2 points for small errors (such
+as one number missing); there weren't many of those.  1 point for the
+following wrong sequence:
+
+        1 1 1 2 1 3 2 4 1 5 3 6 2 7 4 8 1 9 5 10
+
+which is reached by forgetting about the initial 1 and trying to create
+(interleave mystery integers) instead, making the initial 1 part of the
+interleaved values.
+
+
+7.  Infix in metacircular evaluator.
+
+This was an interesting question because the most aesthetically pleasing
+solution isn't the easiest solution.
+
+This problem asks you to change the notation of expressions, not their
+meaning.  EVAL is about expressions; APPLY is about what it means to call a
+function.  So the right place for this change is in EVAL, changing the COND
+clause for procedure calls to this:
+
+      ((application? exp)
+       (let ((left (eval (operator exp) env)))
+	 (if (or (compound-procedure? left)
+		 (primitive-procedure? left))
+	     (apply left (list-of-values (operands exp) env))
+	     (if (= (length exp) 3)
+		 (apply (eval (cadr exp) env)
+			(list left (eval (caddr exp) env)))
+		 (error "Applying non-procedure" left)))))
+
+It's important to do the evaluating of subexpressions exactly right:  only
+once each (just in case the expression involves side effects), but before
+testing for procedureness (because it's the value that's a procedure -- or a
+number, if you're testing for numbers -- not the expression).  That's why I
+had to use a LET to save the result of evaluating the first subexpression.
+
+This is an important point, missed by many students.  The example in the
+exam was just (2 + 3), but it should also work to say (x + 3), or
+((2 * 5) + 3), and in those cases the first subexpression is not itself
+a number.  The *value* of the expression is a number.  Similarly, if you're
+looking at the second subexpression, the problem could be
+        (2 (car (list + - *)) 3)
+in which the second subexpression has an arithmetic operator as its value.
+
+All of that is avoided if you make the change in APPLY, where you take apart
+the arguments you're given and rearrange them if needed.  But it's not an
+aesthetically pleasing solution, partly because applying a procedure to
+arguments is a semantic operation that shouldn't know anything about the
+shape of the expression the user typed, and partly because it means
+disassembling an argument called "arguments" to look for a procedure in it,
+and using the argument called "procedure" as an argument.
+
+Another solution would be to have an intermediate step between EVAL and APPLY,
+like this:
+
+(define (eval exp env)
+  (cond ...
+	((application? exp) (check-infix (list-of-values exp env)))
+	...))
+
+(define (check-infix values)
+  (if (and (not (meta-procedure? (car values)))
+	   (= (length values) 3)
+	   (meta-procedure? (cadr values)))
+      (apply (cadr values) (cons (car values) (cddr values)))
+      (apply (car values) (cdr values))))
+
+(define (meta-procedure? thing)
+  (or (primitive-procedure? thing)
+      (compound-procedure? thing)))
+
+Some solutions treated the problem as one of syntactic rewriting, like
+changing a COND to an IF or vice versa.  This can work, except for the fact
+that you have to partly evaluate the expression in order to know whether or
+not to do the rewriting, and then you'll end up evaluating something twice.
+
+Another solution, very clever and elegant in its intent, has the same
+problem of double evaluation: rewriting the OPERATOR and OPERANDS selectors,
+similar in spirit to the way the selectors for a DEFINE expression recognize
+the implicit-lambda special case.  But in the DEFINE situation, we can tell
+just from the notation -- the syntax -- whether or not an implicit lambda is
+involved.  In the case of infix arithmetic we're not sure until we've
+evaluated some subexpressions.
+
+Other solutions reordered the expression by mutation.  We didn't take off
+for that if it was otherwise correct, but you should try not to develop the
+habit of mutating data structures that you get as arguments unless that's
+specifically in the "contract" with the caller of your procedure.  That same
+data structure might be shared with some other purpose.
+
+The intent of the problem was that *any* two-argument procedure should be
+usable in infix notation.  The problem statement says "[i]f a compound
+expression has three subexpressions, of which the second is a procedure but
+the first isn't..."  But since the problem statement did also mention "infix
+arithmetic," we accepted solutions that work only for the specific operator
+symbols +, -, *, and so on.  However, such solutions aren't very Schemely,
+since the binding of those symbols to arithmetic functions isn't guaranteed.
+A Scheme program could say
+
+        (let ((plus +) (+ word)) ...)
+
+and then the value of (+ 3 4) would be 34!
+
+Note how my solution checks for a procedure.  Strictly speaking, you can't
+use PROCEDURE? to check, because that's a Scheme primitive that checks for
+whether something is a procedure in the underlying Scheme, not a procedure
+in the metacircular Scheme.  But we didn't take off for this subtle error.
+
+
+Scoring:
+
+4  correct
+
+3  subexpression(s) evaluated twice
+   failure to check that the first subexpression isn't a procedure
+	[consider the case (map - '(4 5 6)) which isn't infix!]
+
+2  testing unevaluated subexpressions for being procedures or numbers
+
+1  no evaluation at all
+   infix works but prefix doesn't
+
+0  references to line-obj or other such Logo interpreter structures
+
+Of course not every error is listed above, but these are the common ones.
+
+
+8.  Logic programming
+
+(a) Less
+
+The solution we were expecting was this:
+
+(rule (less () (a . ?y)))           ; 0 < anything positive
+
+(rule (less (a . ?x) (a . ?y))      ; if x < y then x+1 < y+1
+      (less ?x ?y))
+
+Several variants were also okay.  The first rule above could be replaced by
+
+(rule (less () ?x)
+      (not (same ?x ())))
+
+but not just by
+
+(rule (less () ?x))       ; wrong!
+
+because that would allow the case 0 < 0, and not by
+
+(rule (less () (?x)))     ; wrong!
+
+because that only allows for 0 < 1, not for other larger numbers.  But
+having a 0 < 1 rule is okay if you also include a rule
+
+(rule (less ?x (a . ?y))            ; if x < y then x < y+1
+      (less ?x ?y))
+
+But it's quite wrong to have a rule, as many papers did, that if x < y
+then x+1 < y.  That's not true!
+
+(Some combinations of these rules would lead to the query system giving
+the same answer more than once, which is unaesthetic.  The first set of
+rules above avoid that.)
+
+Another approach would use PLUS, which you're given:
+
+(rule (less ?x ?y)
+      (plus ?x (a . ?z) ?y))
+
+This says that x < y if adding some positive number to x gives y.  This is
+elegant because a single rule handles all cases.
+
+
+(b) Divide
+
+Only one rule is needed:
+
+(rule (divide ?dividend ?divisor ?quotient ?remainder)
+      (and (times ?divisor ?quotient ?x)
+	   (plus ?x ?remainder ?dividend)
+	   (less ?remainder ?divisor)))
+
+The third clause is needed to prevent solutions such as 12/4 = 1 remainder 8.
+
+Many people included a lot of base case rules for dividing zero by things,
+dividing things by zero, and so on -- or wrote the rules to exclude zero by
+calling the divisor (a . ?foo).  None of this is necessary; there won't be
+any successful matches of this rule when the divisor is zero.  (This is
+easy to prove: the remainder would have to be less than zero!)
+
+The reason no base case is needed is that this is not a recursive rule;
+there is no reference to DIVIDE in the conditions of the rule.  There is
+still some recursion going on, but it's hidden inside the PLUS and TIMES
+rules.
+
+Scoring:  Each half was worth 2 points if correct, 1 point for a solution that
+has the general idea but with details wrong.  (A common mistake was to think
+that the remainder has to be less than the quotient, or less than the dividend.)
+
+No credit for composition of functions:
+
+  (plus (times ?divisor ?quotient) ?remainder ?dividend)  ; WRONG WRONG WRONG!!!
+
+
+9.  Environment diagram
+
+In the diagram there are three frames:
+
+G:  x=3, y=4, foo=P2 [see below]    (the global frame)
+E1: x=7, extends G
+E2: y=10, extends E1
+
+and two procedures:
+
+P1: parameter x, body (lambda (y) (+ x y)), created in G
+P2: parameter y, body (+ x y), created in E1
+
+When we define FOO, Scheme evaluates the expression
+
+     ( (lambda (x) (lambda (y) (+ x y)))
+       (+ x y) )
+
+The value of the first subexpression is procedure P1, created in the
+global environment (obviously, since it's the only one we have so far).
+The value of the second subexpression is 7, computed using the global
+values of X and Y.
+
+We invoke P1, creating environment E1, in which P1's parameter X is bound to
+the actual argument value 7.  In that new environment we evaluate the body
+of P1, which is another lambda expression, creating P2.
+
+Then DEFINE binds FOO to that result, P2, in the global environment.
+
+When we evaluate the expression (foo 10), environment E2 is created.  FOO's
+parameter Y is bound to the argument value 10, in the new frame.  Then we
+evaluate the body of P2, (+ x y), using the values in E2: x=7 (from E1),
+y=10.  So the answer is 17.
+
+
+Scoring: 1 point for the answer 17.  For the diagram, 3 points minus the
+number of mistakes.  In counting mistakes we looked for three frames,
+two procedures, and five arrows (two arrows extending environments,
+two arrows from procedures to environments, and the arrow binding FOO).
+
+There were too many rearrangement errors to classify, but one common error
+that's worth mention was to say that in E1, X is bound to x+y.  By the time
+E1 is created, we no longer know where the argument value 7 came from;
+that's what it means to say that Scheme uses applicative order.
+
+
+10.  Locate.
+
+The most elegant solution, I think, is this:
+
+(define (locate value struct)
+  (define (help struct fn)
+    (cond ((equal? value struct) fn)
+	  ((pair? struct)
+	   (or (help (car struct) (compose car fn))
+	       (help (cdr struct) (compose cdr fn))))
+	  (else #f)))
+  (help struct (lambda (x) x)))
+
+This is a case in which an iteration-like style, with a helper procedure
+with an extra argument, makes things simpler instead of more complicated.
+(It's not really iterative, of course, since there's a tree recursion,
+but the second recursion, for the cdr, *is* iterative.)
+
+Here's a more straightforward solution:
+
+(define (locate value struct)
+  (cond ((equal? value struct) (lambda (x) x))
+	((pair? struct)
+	 (let ((left (locate value (car struct))))
+	   (if left
+	       (compose left car)
+	       (let ((right (locate value (cdr struct))))
+		 (if right
+		     (compose right cdr)
+		     #f)))))
+	(else #f)))
+
+Note that for both the car and the cdr you have to check whether the
+recursive call actually returned a procedure, rather than #F, before you
+try to compose the procedure with something.
+
+Instead of using COMPOSE you could equivalently use lambda expressions:
+               (lambda (x) (left (car x)))
+
+Notice, by the way, that the iterative-style solution does the composing
+backwards from the recursive-style solution; this is analogous to the list
+reversal that plagues iterative solutions to list-building problems.
+
+One point that many students missed is that the problem says "If the value
+is not found in the structure, LOCATE should return #F" -- not a procedure
+that returns #F!  So you can't say
+
+(define (locate value struct)
+  (lambda (other-struct) ...))         ; wrong
+
+Another commonly missed point is that the problem does *not* say the values
+have to be atomic.  (locate '(a b) '(x y (a b) z)) should work, returning
+the procedure caddr.  In particular, this means that solutions that flatten
+the structure into a simple sequence of atoms, although clever in a way,
+miss the point and aren't satisfactory.
+
+Even worse were the solutions that assume the values are numbers, just
+because the given example had numbers.  A relatively mild version of that
+was to use = for equality checking; much worse was to use list-ref to look
+for the desired element.
+
+A couple of students used AMB in their solutions.  Although we had in mind
+a solution using standard Scheme, we would have allowed this, because it's
+such an appropriate idea -- the problem involves backtracking, so a
+nondeterministic solution makes sense.  But actually getting it right is
+tricky, and nobody managed it:
+
+(define (locate value struct)
+  (define (locate1)
+    (define (help struct fn)
+      (cond ((equal? value struct) fn)
+	    (else (require (pair? struct))
+		  (let ((cxr (amb car cdr)))
+		    (help (cxr struct) (compose cxr fn))))))
+    (help struct (lambda (x) x)))
+  (amb (locate1) #f))
+
+That LOCATE1 subprocedure is required because in case of failure, the
+natural response of the nondeterministic evaluator is to print a message
+saying no more values were found, but we want it to return #F to some
+calling procedure.
+
+Many students made the program much more complicated than necessary, with
+special cases for (car struct), (cadr struct), etc.  Partly this is because
+students don't believe in leaf nodes of trees, and partly it's because
+some students found a somewhat similar problem, called SELECT, in a previous
+exam in the course reader.  But SELECT really did require complications,
+because the first element of a sublist had a special meaning in that problem.
+Here the elements are treated uniformly.
+
+
+Scoring:
+
+4  correct
+3  small errors (typical: only works for atoms, only works if no #F in a list,
+   returns (lambda (x) #f) instead of #f)
+2  has the idea (domain and range correct, uses tree recursion) but
+   more serious errors
+1  not tree recursive (typical: if the car is a list, and doesn't have the
+   value, then the cdr isn't checked)
+0  incoherent
diff --git a/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Final/f-3.soln.txt b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Final/f-3.soln.txt
new file mode 100644
index 0000000..0c4cc82
--- /dev/null
+++ b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Final/f-3.soln.txt
@@ -0,0 +1,1125 @@
+CS 61A		Solutions to sample final exam #3
+
+1.  Domain and range
+
+The domain of a procedure is the TYPE of thing(s) it accepts as argument(s).
+The range is the TYPE of thing it returns.  So we wanted types as the answers
+to this question.  That's generally what you gave for the domain, but for the
+range, several people instead gave explanations of the purpose of the
+procedure, e.g., "Range: the children of the tree node."
+
+(a) CHILDREN
+
+CHILDREN takes one argument, a Tree (which is the same as a node).
+It returns a forest, which is a list of Trees.  So:
+
+	Domain: TREE or NODE
+	Range:  FOREST or LIST OF TREES or just LIST
+
+Most people got this one.
+
+(b) OWNER
+
+OWNER takes one argument, a THING object.  It returns the *name of* the
+person who owns the thing (not the person, not the name of the thing).
+A name is a word, not an object!  So:
+
+	Domain: OBJECT or THING OBJECT or THING INSTANCE
+	Range:  WORD
+
+We also accepted NAME for the range, although that isn't really a type.
+The most common wrong answer for the range was PERSON; that's a kind of
+object, not a word.  A fairly common wrong answer for the domain was CLASS;
+the procedure takes a particular thing as its argument, not the class of all
+things.  Another common wrong answer was PROCEDURE; it's true that we use
+procedures to represent objects, but not every procedure is an object, and
+not every procedure can be used as the argument to OWNER.
+
+(c) SET-CDR!
+
+SET-CDR! takes two arguments; the first must be a pair, and the second can be
+of any type.  Its return value is unspecified, since it is used for its effect
+rather than for its return value, so we accepted anything for the range in
+this part.
+
+	Domain: PAIR and ANYTHING (you had to say both).
+	Range:  UNSPECIFIED (but we accepted anything).
+
+We didn't accept LIST for the domain; there is no requirement that the first
+argument to SET-CDR! be a pair whose cdr is a list (which is what it means for
+a pair to be a list).  Also, the LIST domain would include the empty list,
+which can't be used as the first argument to SET-CDR!.
+
+Scoring: One point each, all or nothing.
+
+
+2.  Data abstraction
+
+The argument is a LIST of RATIONALs.  For the list itself, the appropriate
+selectors are CAR and CDR.  (Constructors for lists include CONS, LIST, and
+APPEND, but in this problem we are not constructing a list!)  For a rational
+number, the constructor is MAKE-RAT and the selectors are NUMER and DENOM.
+So the corrected version is
+
+(define (ratprod lst)
+  (define (helper lst n d)
+    (if (null? lst)
+	(MAKE-RAT n d)
+	(helper (CDR lst) (* n (NUMER (CAR lst)) (* d (DENOM (CAR lst)))))))
+  (helper lst 1 1))
+
+The call to CDR doesn't change because it is selecting part of a list, not
+part of a single rational number.  The calls to CAAR and CDAR do change,
+as shown above; they both select the first element of the list (CAR), and
+each then selects one piece of a rational number (NUMER or DENOM).
+
+Scoring: -1 point per error, either a required change not made or something
+changed that shouldn't have been.  But 0 points if no correct change was
+made at all (e.g., if the question was left blank).
+
+
+3.  Order of growth
+
+(a)
+
+(define (two-to-the n)
+  (if (zero? n)
+      1
+      (let ((prev (two-to-the (- n 1))))
+	(* prev 2) )))
+
+Each call to this procedure does three constant-time operations (ZERO?, -,
+and *) in addition to making one recursive call.  So there are N recursive
+calls, each of which takes constant time.  Therefore, this procedure takes
+time Theta(N).
+
+(b)
+
+(define (two-to-the n)
+  (if (zero? n)
+      1
+      (let ((prev (two-to-the (- n 1))))
+	(+ prev prev) )))
+
+The only difference here is (+ PREV PREV) instead of (* PREV 2).  This
+is still a single, constant-time arithmetic operation, although both operands
+are the variable PREV rather than including the explicit number 2.  But
+finding the value of a variable is also constant time, so this doesn't affect
+the program's running time, which is still Theta(N).
+
+(c)
+
+(define (two-to-the n)
+  (if (zero? n)
+      1
+      (+ (two-to-the (- n 1))
+	 (two-to-the (- n 1)) )))
+
+In this version, each call to TWO-TO-THE gives rise to *two* recursive
+calls.  So, for example, (two-to-the 5) calls (two-to-the 4) twice; each
+of those makes two calls, for a total of four calls of (two-to-the 3).
+Similarly, there are eight (two-to-the 2) calls and 16 of (two-to-the 1).
+Increasing N by 1 doubles the total number of recursive calls, so the
+running time for this procedure is exponential, Theta(2^N).
+
+The most common error was to think that the last version was Theta(N^2).
+
+Scoring: One point each.
+
+
+4.  Functions of functions.
+
+The point of this question is to illustrate some of the ways in which
+functions can be manipulated on their own, without explicit reference to
+the arguments of the functions.  You've seen COMPOSE before, in lecture;
+the other two tools given here are similar in spirit.
+
+One way to think about these questions would be to try writing the
+desired procedure without using COMPOSE, SPECIALIZE, or SWAP-ARGS, and
+then think about how you did it.
+
+[a] INITIALS
+
+(define (initials sent)
+  (every first sent))
+
+So INITIALS is a specialized version of EVERY, in which the first
+(procedure) argument is FIRST.  Thus we have the answer:
+
+(define initials (specialize every first))
+
+
+[b] POSITIVE?
+
+(define (positive num)
+  (> num 0))
+
+This is a specialization of >, in which the *second* argument is held
+constant (zero), not the first argument as in INITIALS.  So SPECIALIZE
+won't quite do the job by itself.  One solution would be to use <
+instead of >:
+
+(define (positive num)
+  (< 0 num))
+
+(define positive (specialize < 0))
+
+but that wasn't one of the choices.  Instead we use SWAP-ARGS to get
+the arguments in the right order:
+
+(define positive (specialize (swap-args >) 0))
+
+
+[c] LEAF?
+
+(define (leaf? node)
+  (null? (children node))
+
+This is a composition of functions:
+
+(define leaf? (compose null? children))
+
+
+Scoring: One point each.
+
+
+5.  Mystery function on Trees
+
+(define (mystery tree)
+  (if (null? (children tree))
+      (make-tree (datum tree) '())
+      (make-tree (+ (datum tree) 100)
+		 (map mystery (cdr (children tree))))))
+
+This function says:  If the node is a leaf, return a leaf node with the
+same datum.  (This is actually unnecessarily complicated; it could have
+just returned the argument TREE itself, since the node it constructs has
+the same datum and the same (empty) children.)  If the node isn't a leaf,
+add 100 to its datum, and recursively apply the same function to its
+children, but omit the first child (because of the CDR call).
+
+In the given tree, the root node (datum 1) has three children, so we add
+100 to its datum (giving 101), we omit the subtree headed by the node with
+datum 2, and we recursively process nodes 3 and 4.
+
+Node 3 (I'm using this as an abbreviation for "the node with datum 3" and
+similarly for the other nodes) has two children, so we add 100 to its
+datum, omit the first child (6), and recursively process the other child
+(node 7).
+
+Node 7 has no children, so we just return a leaf with datum 7.
+
+Node 4 has one child.  So we add 100 to its datum, omit its first (only)
+child 8, and recursively process its other children -- but there aren't
+any, so the node with datum 104 will be a leaf node in the resulting tree.
+
+Omitting a node doesn't just mean omitting the datum of that node; we
+never look at its children either.  So we don't have to think about nodes
+5, 9, and 10.
+
+Don't forget that this function builds a new tree!  It doesn't mutate the
+argument tree.  In particular, one common wrong answer was to return a
+tree with 10 nodes, just like the argument tree, but with 100 added to
+some of the data.  The correct answer is a tree with only the four nodes
+mentioned earlier as part of the result:
+
+			       101
+			      /   \
+			    103   104
+			     |
+			     7
+
+Another too-common mistake was to draw a tree in which some nodes have
+lists as the datum.  For example, the child of the 103 node was shown as
+having (7) as its datum, or the 104 node had a child with the empty list
+as its datum.  These errors, I think, come from not respecting the data
+abstraction, but instead trying to translate the tree selectors and
+constructor into operations on pairs.  As you can see from the explanation
+above, there is no need to think about how tree nodes are represented!  The
+only pair operation used is the CDR in the procedure, and that's because
+(CHILDREN TREE) returns a forest -- a list of trees -- rather than a single
+tree node.
+
+Several people thought that a Scheme error would result from the expression
+
+	(map mystery (cdr (children tree)))
+
+when it is applied to the 4 node, which has only one child, because in this
+case the expression is equivalent to
+
+	(map mystery '())
+
+But there's nothing wrong with this -- MAP is happy to take the empty list
+as its second argument, in which case it returns the empty list without
+ever calling MYSTERY.  Empty lists are legitimate lists!
+
+
+Scoring:
+
+5  Correct.
+
+4  Correct except that instead of 101, 103, and 104, the values in those
+   nodes are computed by some different arithmetic; most commonly these
+   nodes have the data 101, 301, and 401.  Node 7 must be correct.
+
+3  Right shape, but one incorrect datum (most often 107 instead of 7).
+
+2  The four correct nodes plus one or two extras, including the case of
+   "error" as a child of node 104.
+
+2  The solution obtained by ignoring the CDR in the procedure: 10 nodes
+   in the same shape as the original, but with 1, 2, 3, 4, and 8 changed
+   to 101, 102, 103, 104, and 108.
+
+0  "Error" as the complete answer without an explanation.
+
+0  Any list structure in the tree data.
+
+0  Anything else, including the "mutation" solution mentioned earlier with
+   10 nodes like the original but with 1, 3, and 4 changed to 101, 103, 104.
+
+
+
+6.  Scheme to OOP
+
+We are given
+
+(define foo
+  (let ((a 3))
+    (LAMBDA (B)			;; This is the class FOO
+      (let ((c 4))
+	(LAMBDA (MESSAGE)	;; This is the instance's dispatch procedure
+	  (cond ((eq? message 'hi)
+		 (+ a b))
+		(else
+		 (+ c message))))))))
+
+The scope of the LET variable A encloses the procedure representing the class,
+so it's a class variable.  B is an argument to the class, so it's an
+instantiation variable.  And C is inside the scope of the class, but outside
+the scope of the instance, so it's an instance variable -- each instance has
+its own C.  Therefore:
+
+(define-class (foo b)
+  (class-vars (a 3))
+  (instance-vars (c 4))
+  (method (hi)
+    (+ a b))
+  (default-method
+    (+ c message)))
+
+The dispatch procedure looks explicitly for the message HI and provides
+a method for it; the ELSE clause in the dispatch procedure handles any
+other message, so it's a default method.
+
+Most people got the translation of the LET expressions for A and C right,
+although a few people reversed them and a few people thought A and C were
+the same kind of variable.  B was trickier; some people didn't realize
+that that LAMBDA represents the class, and instead thought that B was a
+formal parameter of a method.
+
+Similarly, some people thought the inner LAMBDA expression represents a
+method rather than a dispatch procedure, so they wrote methods with
+MESSAGE as a parameter.
+
+As in any object class definition, it's possible to have only a default
+method that checks for particular messages explicitly:
+
+  (default-method
+    (if (eq? message 'hi)
+	(+ a b)
+	(+ c message)))
+
+and we accepted that, although it's contrary to the spirit of OOP.  But
+most people who were confused about the meaning of the inner LAMBDA came
+up with incorrect solutions, such as
+
+  (method (hi message b) ...)
+  (default-method (message) ...)
+  (method (hi) (if ...))
+
+Scoring:  The correct solution has five components: the use of B as an
+instantiation variable, and the four clauses within the define-class (A, C,
+HI, and DEFAULT-METHOD).  We subtracted one point for each missing or
+incorrect component.  Incorrect solutions that tried to combine the HI
+method with the default method lost both points, except for the
+  (method (hi) (if ...))
+version (no parameter to HI!), which lost only one point for the methods.
+
+
+7.  Environment diagrams
+
+The diagrams have many features in common:  They all have a global frame
+and an additional frame E1; they all have a symbol F bound to a procedure.
+But there are two things that differ among diagrams:
+
+	* The symbol F is in frame G (diagrams A and B) or in frame
+	  E1 (diagrams C and D).
+
+	* The procedure's right bubble points to frame G (diagrams
+	  A and C) or to frame E1 (diagrams B and D).
+
+So, to figure out this question, for each of the four Scheme programs we
+have to ask "where is the procedure created?" and "where is F bound?"
+
+(let ((f (lambda (x) x)))
+ 'okay) 
+
+	Here the LAMBDA expression is evaluated in the global environment,
+	because LET value expressions are evaluated *before* the implicit
+	procedure created by the LET is invoked.  But the binding for F is
+	made locally, in the frame E1 that's created by the LET.  So this
+	is diagram C: procedure points to G, F bound in E1.
+
+(define f
+ (let ()
+   (lambda (x) x)))
+
+	This time the LAMBDA expression is evaluated in the body of the LET,
+	so its current environment is E1, and so that's what the right bubble
+	remembers.  But the DEFINE is in the global environment, so that's
+	where F is bound.  This is diagram B: procedure points to E1, F
+	bound in G.
+
+(let ()
+ (define f (lambda (x) x)))
+
+	This time both the LAMBDA and the DEFINE are in the body of the LET,
+	so both of them have E1 as the current environment.  This is diagram
+	D: procedure points to E1, F bound in E1.
+
+(define (f) f)
+(f)
+
+	Here we have a straightforward global definition of a procedure F,
+	so both the (implicit) LAMBDA and the DEFINE happen in G.  So this
+	is diagram A: procedure points to G, F bound in G.  (Frame E1 is
+	created by the second, separate expression, which invokes F.)
+
+Most students got this correct.  The most common wrong answer was DBCA.
+Choosing D for the first expression comes from the frequent misunderstanding
+in which students think that the expressions that provide the values for the
+LET variables are evaluated inside the scope of the LET.  I'm not sure how
+anyone would choose C for the third expression, but probably it's because you
+assumed (correctly) that each diagram was used once.
+
+Scoring: one point each.
+
+
+8.  CADR for message-passing pairs
+
+A pair made by MAKE-PAIR can handle CAR and CDR messages directly because
+its local state variables X and Y contain the desired values.  But in order
+to handle the CADR message, it has to find its own CDR (which is Y) and
+send a CAR message to that other pair:
+
+(define (make-pair x y)
+  (lambda (msg)
+    (cond ((eq? msg 'car) x)
+	  ((eq? msg 'cdr) y)
+	  ((EQ? MSG 'CADR) (Y 'CAR))	;; <<=== This line added!
+	  (else (error "I have no idea what you're talking about.")) )))
+
+One common mistake was (ASK Y 'CAR); this has the idea, but we're using
+plain Scheme message passing, not the OOP language.
+
+Many students used roundabout means to find the pair's CDR, such as
+
+	   ((eq? msg 'cadr) (((make-pair x y) 'cdr) 'car))
+
+presumably because you mistrusted a simple Y as something you can invoke.
+This works, but it really violates the spirit of the problem -- it creates a
+new pair every time you look at the pair -- and didn't get full credit.
+
+Another common error was (CAR Y).  Unless you explicitly redefine CAR to
+use the message-passing pairs, this will invoke the ordinary CAR that
+expects a built-in Scheme pair as its argument, not a procedure.  We
+named the pair constructor MAKE-PAIR rather than CONS to make it clear
+that we didn't mean to eliminate the regular pairs, and our example says
+(ABC 'CAR) rather than (CAR ABC).
+
+Of course the worst mistake was to build the specific example ABC into
+the solution!
+
+Scoring:
+
+3  Correct.
+
+2  (ASK Y 'CAR)
+
+2  (X 'CDR)		; this would give the CDAR, not the CADR.
+
+2  Working solutions that call MAKE-PAIR.
+
+1  (X 'CAR) or (Y 'CDR)	; CAAR and CDDR.
+
+0  Anything else, including (CAR Y).
+
+
+
+9.  List mutation.
+
+Here is the box-and-pointer diagram *before* doing any mutation:
+
+---> XX------------> XX------------> X/
+     |               |               |
+     V               V               V
+
+     XX---> X/       XX---> X/       E
+     |      |        |      |
+     V      V        V      V
+
+     A      B        C      D
+
+The expression (SET-CAR! (CADR LST) (CDDR LST)) modifies the pair that is
+the CADR of the original list -- the CAR of the CDR.  (CDR LST) is the
+second pair of the spine, in the top row.  CAR of that pair is the first
+pair in the spine of the sublist (C D).  So we are going to change the CAR
+of that pair, replacing C with something.  With what?  With the value of
+(CDDR LST), the second argument to SET-CAR!.  (CDDR LST) is the third
+pair of the spine of the entire list, the one whose CAR is E.  So after
+this first mutation we have
+
+---> XX------------> XX---------->-> X/
+     |               |          /    |
+     V               V          *    V
+                                *
+     XX---> X/       XX---> X/  *    E
+     |      |        *      |   *
+     V      V        *      V   *
+                     *          *
+     A      B        *      D   *
+                     *          *
+                     ************
+
+The second mutation, (SET-CAR! (CAR LST) (CADDR LST)), modifies (CAR LST),
+which is the first element of the big list -- the first pair of the spine
+of the sublist (A B).  We change the CAR of this pair, so that instead of
+pointing to A, it points to the CADDR of the big list, which is the third
+element, the symbol E:
+
+---> XX------------> XX---------->-> X/
+     |               |          /    |
+     V               V          *    V
+                                *
+     XX---> X/       XX---> X/  *    E
+     *      |        *      |   *
+     *      V        *      V   *    ^
+     *               *          *    *
+     *      B        *      D   *    *
+     *               *          *    *
+     *               ************    *
+     *                               *
+     *********************************
+
+Notice that the first mutation points to a pair, not to E, but the second
+one points to E.  This is the difference between (CDDR LST) and (CADDR LST).
+
+It's okay if you draw another E underneath the relevant pair, instead of
+drawing an arrow over to the original E.  Since two equal symbols are always
+EQ, it's not important to distinguish two equal symbols in the diagram.
+
+The third mutation is (SET-CDR! (CAR LST) (CDAR LST)).  This says, "change
+the CDR of (CAR LST) to the CDR of (CAR LST)"!  In other words, it doesn't
+really change anything:
+
+---> XX------------> XX---------->-> X/
+     |               |          /    |
+     V               V          *    V
+                                *
+     XX***> X/       XX---> X/  *    E
+     *      |        *      |   *
+     *      V        *      V   *    ^
+     *               *          *    *
+     *      B        *      D   *    *
+     *               *          *    *
+     *               ************    *
+     *                               *
+     *********************************
+
+Finally we have (SET-CAR! (CDDR LST) 'X).  This modifies (CDDR LST), which
+is the last pair of the spine.  Its CAR used to point to E, but now points
+to X instead:
+
+---> XX------------> XX---------->-> X/
+     |               |          /    *
+     V               V          *    *
+                                *    V
+     XX***> X/       XX---> X/  *    
+     *      |        *      |   *    X
+     *      V        *      V   *    
+     *               *          *    
+     *      B        *      D   *    E
+     *               *          *    
+     *               ************    ^
+     *                               *
+     *********************************
+
+So the printed representation of the final result is:
+
+	((E B) ((X) D) X)
+
+The most common wrong answer was ((X B) ((X) D) X).  This comes from thinking
+that the last mutation changes *everything* that points to E so that it points
+to X instead.  But that would be true only if the pair (CAR LST) pointed to
+the *pair* (CDDR LST), whose CAR is changed from E to X, rather than pointing
+directly to E.
+
+Another common wrong answer was ((E B) (X D) X), ignoring the fact that the
+first mutation replaces the letter C with the *pair* (CDDR LST), which is a
+list, not a symbol; its printed representation is (X).
+
+A common error in the diagram itself was to create new pairs, most often
+making a *copy of* (CDDR LST) to be the CAR of (CADR LST).
+
+Another misunderstanding, which led to huge errors in the diagram, was to
+think that (CAR LST) means the first *pair in the spine* of LST, rather
+than the first *element* of LST.  Similarly, students misinterpreted
+(CADR LST) to mean the second pair of the spine, and so on.
+
+Scoring:  We subtracted one point per wrong change in the diagram (out of
+the four possible changes), and one point if the printed representation
+didn't match your diagram.
+
+
+10.  Scheme vs Logo evaluators
+
+In Scheme, evaluating the expression (+ A 3) requires the evaluator to look up
+two variables: + and A.  Since we are giving MC-EVAL an environment that only
+has a binding for A, this first expression gives the result
+
+	ERROR: Unbound variable +
+
+In Logo, procedure names aren't part of the environment, but are found in a
+separate, global table that's used automatically by LOGO-EVAL.  So in order to
+evaluate the Logo expression (SUM 2 :A), we have to look up A in the
+environment, but we don't need SUM in the environment.  Therefore the result
+of this evaluation is
+
+	5
+
+
+One too-common error was to say (+ A 3) as the value returned in the first
+case.  Presumably students who said this were reacting to the fact that the
+expression (+ A 3) is quoted when used as an argument to MC-EVAL.  But this
+just means that the argument is (+ A 3) rather than being the result of
+evaluating (+ A 3) in the underlying STk evaluator!
+
+Scoring:  Two points each.  We accepted any ERROR message for the first part.
+
+For the second part, we accepted 6 instead of 5 (because it's not important
+if you didn't notice that the second expression used 2 rather than 3) for
+full credit.
+
+We gave half credit (one point) to either of two particular wrong answers
+to the second part:
+
+	You don't say what to do with 5
+
+(which would be correct if we were calling DRIVER-LOOP instead of LOGO-EVAL),
+and
+
+	5  =no-value=
+
+(which can't be correct, since it's two values instead of one, but presumably
+is meant to show the values computed by EVAL-LINE, although that isn't right
+either because EVAL-LINE returns a value as soon as it gets anything other
+than =no-value= from evaluating an expression).
+
+
+11.  Streams
+
+The first two elements are explicitly given as A and B.  The remaining
+elements are the result of interleaving two streams, so we can draw a
+picture like this:
+
+
+	A  B  ___       ___       ___       ___
+
+                   ___       ___       ___       ___
+
+
+The second argument to INTERLEAVE is a stream containing only elements
+that are the symbol B, so we can start to fill this in:
+
+
+	A  B  ___       ___       ___       ___
+
+                   _B_       _B_       _B_       _B_
+
+
+To fill in the top row, we just copy the entire stream FOO.  We already
+know FOO's first two elements, so we can fill those in, and that tells us
+FOO's third and fifth elements.  (Its fourth element is the first B on the
+bottom row.)
+
+
+	A  B  _A_       _B_       _A_       _B_
+
+                   _B_       _B_       _B_       _B_
+
+
+Putting this back into a single row gives the solution:
+
+	A  B  A  B  B  B  A  B  B  B
+
+
+Scoring:  We subtracted one point per wrong letter.  This means that the
+common error in which only the first letter is A [A B B B B B B B B B B]
+got one point.
+
+Exception:  Some people apparently think that STREAM-FILTER keeps only
+the elements that *don't* satisfy the predicate, so they put a stream of
+As in the bottom row rather than a stream of Bs.  This gives the incorrect
+solution A B A A B A A A A A, to which we gave one point.
+
+
+12.  Logic programming
+
+As a reminder, here's ASSOC written in Scheme:
+
+(define (assoc key alist)
+  (cond ((null? alist) #f)
+	((equal? key (caar alist)) (car alist))
+	(else (assoc key (cdr alist)))))
+
+The first COND clause does not have any analog in the logic program!  In
+logic programming, if nothing satisfies the question we're asking, we just
+don't match any rule.  We don't want a rule that shows a value of #F.
+
+Here's the rule corresponding to the second COND clause:
+
+(assert! (rule (assoc ?key ((?key . ?value) . ?rest) (?key . ?value))))
+
+No condition is necessary for this rule; the pattern says it all.  But
+it would be okay to show this rule in a form closer to that of the Scheme
+program:
+
+(assert! (rule (assoc ?key (?car . ?cdr) ?car)
+	       (and (same ?car (?caar . ?cdar))
+		    (same ?key ?caar))))
+
+The second COND clause is a little tricky, because we only want to allow
+the recursion if the key doesn't match the first entry.  In Scheme, COND
+automatically handles this, because COND can only return one value, so it
+doesn't look at any clauses after the first successful one.  But logic
+programming allows multiple results, so we have to explicitly disable the
+recursion in case of a match:
+
+(assert! (rule (assoc ?key ((?caar . ?cdar) . ?rest) ?result)
+	       (and (assoc ?key ?rest ?result)
+		    (not (same ?key ?caar)))))
+
+To make this work we also have to define the SAME relation:
+
+(assert! (rule (same ?x ?x)))
+
+but we didn't require this to be explicitly included in your solution.
+
+
+Some people tried to use a single rule that matches any association list
+that has the desired key anywhere in it, like this:
+
+(rule (assoc ?key (?left . (?key . ?value) . ?right) (?key . ?value))) ;WRONG!
+
+This isn't such a bad idea, except that there is no (x . y . z) notation for
+a list that has element Y in the middle.  But the desired result can be
+obtained using the APPEND rules:
+
+(assert! (rule (assoc ?key ?alist (?key . ?value))
+	       (and (append ?left ((?key . ?value) . ?right) ?alist)
+		    (not (assoc ?key ?left ?something)))))
+
+The NOT clause is required to eliminate duplicate matching keys.  Alas,
+most people who tried this didn't quite use APPEND correctly.  The worst
+problem was to try to use it as a function rather than a relation:
+
+	(rule (assoc ?key (append ?left ((?key . ?value) . ?right))
+		          (?key . ?value)))	; WRONG!!!
+
+This is an attempt to use the "return value" from APPEND as part of the
+pattern for the ASSOC rule, but APPEND doesn't return a value.  It's a
+relation that succeeds or fails, and the appended list is one of the
+components of the relation, as in the correct version above.
+
+
+The most common error was to include spurious base cases, such as
+
+	(rule (assoc ?key () #f))	; WRONG!
+
+A more subtle error was to try to eliminate duplicate keys in the
+association list in the wrong rule:
+
+(assert! (rule (assoc ?key ((?key . ?value) . ?rest) (?key . ?value))
+	       (not (assoc ?key ?rest ?something))))	; WRONG!
+
+This rule would find the last matching key, not the first matching key,
+in the association list.
+
+
+Scoring:
+
+5  Correct.
+
+4  Extracts just the key, or just the value, rather than the entire pair.
+
+4  Finds the last matching key rather than the first one.
+
+3  Finds all matching keys (no NOT clause).
+
+3  Spurious base case for empty list.
+
+2  No recursive rule at all.
+
+2  Other "has the idea" but non-working solutions with a rule that tries
+   to match the car of the association list.
+
+0  No rule matching the car of the association list (recursive rule only).
+
+0  Has the example built in (e.g., only works for lists of length four).
+
+0  Composition of functions (like the incorrect APPEND version above).
+
+0  Anything not mentioned above.
+
+
+13.  Concurrency
+
+All of the examples try to call the procedures F and G, which both modify
+the variable X, and must therefore be protected against each other.
+Therefore, we must use the same serializer for both of them.
+
+(parallel-execute (s f) (t g))
+
+	This uses two different serializers for the two thunks, so they
+	are not protected against each other.  This can give rise to
+	INCORRECT RESULTS.
+
+(parallel-execute (s f) (s g))
+
+	This is the correct way to do it -- a single serializer protects
+	the variable X, and every process that depends on X is protected
+	using S.  So it produces NEITHER incorrect results nor deadlock.
+
+(parallel-execute (s (t f)) (t g))
+
+	This has an unnecessary invocation of serializer S.  Both processes
+	are protected by T, so no incorrect results are possible, and nothing
+	is added by calling S also.  But since S is used for only one process,
+	there will be NEITHER incorrect results nor deadlock.
+
+(parallel-execute (s (t f)) (s g))
+
+	This is just like the previous case: S does the needed protection,
+	and T is unhelpful but not harmful either, since only one process
+	uses it.  So NEITHER problem can arise.
+
+(parallel-execute (s (t f)) (t (s g)))
+
+	There won't be incorrect results, since both processes use the same
+	serializer (either S or T can be considered as the useful one).  The
+	second serializer is unnecessary.  But this time, since two processes
+	use the same two serializers, in different orders, DEADLOCK is
+	possible.
+
+Scoring: One point each.
+
+
+14.  Tree to binary tree.
+
+The crucial point here is that two different abstract data types (Tree and
+Binary Tree) are involved.  A binary tree isn't just a Tree!  It's different
+because if a node has exactly one child, a Binary Tree can distinguish whether
+this is the left child or the right child; the Tree type doesn't allow for
+this distinction.  So, for example, you couldn't use the Tree type to
+represent a binary search tree.
+
+We are given a Tree as argument, and asked to return a Binary Tree.
+Therefore, our program should use the *selectors* for the Tree type (namely
+DATUM and CHILDREN), but should use the *constructor* for the Binary Tree
+type (MAKE-BT).
+
+We didn't say explicitly in the problem what the arguments to MAKE-BT should
+be, but we did say it's based on the Binary Tree type in the text (see page
+157), except changing the name from MAKE-TREE to MAKE-BT.  It takes three
+arguments, the three components of a Binary Tree node: entry, left, and right.
+
+(define (tree->bt tree)
+  (if (> (length (children tree)) 2)
+      #f
+      (let ((kids (map tree->bt (children tree))))
+	(cond ((member #f kids) #f)	; propagate failure upward
+	      ((null? kids) (make-bt (datum tree) '() '()))
+	      ((null? (cdr kids)) (make-bt (datum tree) (car kids) '()))
+	      (else (make-bt (datum tree) (car kids) (cadr kids)))))))
+
+The most common error was to forget the first COND clause.  It's not good
+enough to return #F if *this* node has three or more children; we also have to
+return #F if any *child* (or grandchild, etc.) of this node has too many
+children.  So we see if the value returned by any recursive call to TREE->BT
+is false, and if so we return false too.
+
+Since MAKE-BT has separate arguments for the left and right branches,
+we need three COND clauses for each of the possible number of children
+in order to put the child(ren) in the right place(s).
+
+We accepted solutions in which MAKE-BT takes a list of length exactly two,
+every time, to specify the two branches of the new node.  But we didn't accept
+solutions in which MAKE-BT takes a list of any number of children, because
+that interface wouldn't allow the user to distinguish the case of a node with
+only a left child from the case of a node with only a right child.  (In this
+problem we say that we aren't going to create any nodes with only a right
+child, but you can't specify a constructor for Binary Trees that doesn't allow
+for that possibility.)
+
+Another common error was data abstraction violations.  These come in two
+forms:  (1) mixing the selectors and constructors for Trees with those for
+Binary Trees, and (2) using list/pair selectors and constructors (CONS, CAR,
+etc.) for either Trees or Binary Trees.  We considered the first category less
+severe than the second, although either kind of DAV really shows a failure to
+understand the point of data abstraction!  (This is true despite the fact that
+a few students wrote essays to try to justify their violations.)
+
+Another severe error was to try to mutate the tree instead of constructing a
+new data structure.  This was rarely explicit (e.g., using SET-CAR!); the
+usual thing was for students to call MAP, ignore its return value, and think
+(apparently) that something has changed in the argument tree.  We referred to
+this in the grading as the "MAP!" error -- using MAP as if it were a mutator.
+
+Scoring:
+
+6  Correct.
+
+4  Correct except that #F from a child isn't propagated to the parent.
+
+2  Case analysis errors, e.g., two-child nodes handled correctly but
+   one-child nodes handled incorrectly.
+
+2  Tree vs. Binary Tree DAV.
+
+0  Tree vs. Pair DAV [e.g., (CAR TREE)].
+
+0  No deep recursion (grandchildren not examined).
+
+0  Pseudo-mutation (using MAP as if it were MAP! mutator).
+
+0  Anything worse.
+
+
+
+15.  SWAP!
+
+This was a relatively easy mutation problem, since there was no need to
+examine inside any lists found as elements of the argument list.  We only
+care about elements of the top-level list.
+
+The first decision to be made is whether this is a job for SET-CAR! or
+for SET-CDR!.  The best choice is SET-CAR!, because we don't want to change
+which pair comes first in the list's spine, in case some variable used in the
+calling procedure is bound to this list.
+
+We want to mutate the pairs of the spine, not any pairs that might be elements
+of the list.  And we need a temporary variable to remember one of the elements
+while we're doing the swapping.
+
+(define (swap! lst)
+  (cond ((null? lst) lst)
+	((null? (cdr lst)) lst)
+	(else (let ((temp (car lst)))
+		(set-car! lst (cadr lst))
+		(set-car! (cdr lst) temp)
+		(swap! (cddr lst))
+		lst))))
+
+Scoring:
+
+6  Correct.
+
+5  Swaps correctly but doesn't return a value.
+
+5  Correct except for base cases.
+
+4  Has the idea:
+    * Uses a temporary variable; and
+    * SET-CAR! of two pairs, with at least one in the spine; and
+    * Recursive;
+   but...
+     - recurs on (CDR LST) instead of (CDDR LST); or
+     - uses SET-CDR! and reorders correctly but loses the head pair; or
+     - has the wrong value in TEMP (a spine pair instead of an element).
+
+3  (set-car! (CAR lst) (cadr lst)) and (set-car! (CADR lst) temp).
+
+2  Has an idea:
+    - only one SET-CxR!; or
+    - no temporary variable; or
+    - mutates two wrong pairs; or
+    - thinks SET! will change a pair, but also uses SET-CxR!.
+
+0  Other, including:
+    - allocates pairs (CONS, LIST, APPEND, etc.); or
+    - no recursion; or
+    - no SET-CxR!; or
+    - SET! of a non-symbol [e.g., (SET! (CAR LST) (CADR LST))].
+
+
+16.  Partial application in MCE
+
+The feature we want to add, which in the programming language literature is
+generally called "partial application," is used when a procedure is called.
+Procedure calling is the job of MC-APPLY, so that's where we have to make the
+change.  (It's possible to do it elsewhere, but less straightforward.)
+
+We are asked to construct a new procedure.  How do we do that?  The best
+answer is to call MAKE-PROCEDURE.  There's no need to construct and then
+evaluate a LAMBDA expression!
+
+What should the procedure look like?  One solution is to do exactly what's
+shown in the question: a procedure whose body is an invocation of the
+underlying procedure.  But this is actually a little tricky, because when we
+get to APPLY we no longer know what *expression* has that procedure as its
+value!  We only have the procedure itself.  So the easiest thing will be if we
+can create a procedure with the same body as the original procedure.  For
+example, if the original procedure is
+
+	(lambda (base exp)
+	  (cond ((= exp 0) 1)
+		((even? exp) (fast-exp (* base base) (/ exp 2)))
+		(else (* base (fast-exp base (- exp 1))))))
+
+then we'll create a procedure
+
+	(lambda (EXP)		;; only this line is different
+	  (cond ((= exp 0) 1)
+		((even? exp) (fast-exp (* base base) (/ exp 2)))
+		(else (* base (fast-exp base (- exp 1))))))
+
+but we'll create it in an environment with BASE bound to 2, as if the
+user had typed
+
+	(let ((base 2))
+	  (lambda (exp)
+	    (cond ((= exp 0) 1)
+		  ((even? exp) (fast-exp (* base base) (/ exp 2)))
+		  (else (* base (fast-exp base (- exp 1)))))))
+
+But of course we can't build this particular example into the solution;
+it has to work for any procedure, with any number of parameters, and with
+any smaller number of arguments given in the invocation.
+
+(define (mc-apply procedure arguments)
+  (cond ((primitive-procedure? procedure)
+	 (apply-primitive-procedure procedure arguments))
+	((compound-procedure? procedure)
+	 (IF (< (LENGTH ARGUMENTS) (LENGTH (PROCEDURE-PARAMETERS PROCEDURE)))
+	     (MAKE-PROCEDURE
+	      (BUTFIRST-N (LENGTH ARGUMENTS)
+			  (PROCEDURE-PARAMETERS PROCEDURE))	; parameters
+	      (PROCEDURE-BODY PROCEDURE)			; body
+	      (EXTEND-ENVIRONMENT				; environment
+	       (FIRST-N (LENGTH ARGUMENTS)
+			(PROCEDURE-PARAMETERS PROCEDURE))
+	       ARGUMENTS
+	       (PROCEDURE-ENVIRONMENT PROCEDURE))) 	; lexical scope!
+	     (eval-sequence
+	      (procedure-body procedure)
+	      (extend-environment
+	       (procedure-parameters procedure)
+	       arguments
+	       (procedure-environment procedure)))))
+	(else
+	 (error
+	  "Unknown procedure type -- APPLY" procedure))))
+
+This solution uses helper procedures to extract the first N parameters,
+and all but the first N parameters, from the original procedure's list of
+parameters:
+
+(define (first-n n lst)
+  (if (= n 0)
+      '()
+      (cons (car lst) (first-n (- n 1) (cdr lst)))))
+
+(define (butfirst-n n lst)
+  ((repeated cdr n) lst))
+
+This is the most elegant solution, because it deals only with values,
+not with expressions -- there's no need to call MC-EVAL anywhere in it.
+It's also possible to solve the problem by manipulating the text of the
+procedure in various ways.  For example, we could try to substitute the
+argument values for the first N parameters in the body, so we'd get the
+procedure
+
+	(lambda (exp)
+	  (cond ((= exp 0) 1)
+		((even? exp) (fast-exp (* 2 2) (/ exp 2)))
+		(else (* 2 (fast-exp 2 (- exp 1))))))
+
+for our example.  This is trickier than it looks to get correct, though.
+In this example the actual argument is a number, which is self-evaluating.
+But suppose the actual argument value is a non-numeric word or a list.
+It won't work to substitute the argument *value* into the body; we have
+to find the argument *expression* (which means we'd have to do the job in
+MC-EVAL rather than in MC-APPLY), or else we have to quote the value each
+time we substitute it.
+
+The key point is to be clear on the difference between an expression and a
+value -- for example, a LAMBDA expression versus a procedure.  We want to
+return a procedure, so either we call MAKE-PROCEDURE or we call
+
+	(mc-eval (make-lambda ...) some-environment)
+
+Which environment should we extend?  The one in the original procedure,
+of course -- we don't want to break Scheme's lexical scope rule.  Some
+solutions passed the current environment from MC-EVAL to MC-APPLY, thereby
+switching to dynamic scope.
+
+Many students came up with solutions modifying EXTEND-ENVIRONMENT instead of
+modifying MC-APPLY.  This is a reasonable first idea, since the problem is
+about matching formal parameters with actual arguments, and that's the job of
+EXTEND-ENVIRONMENT.  But it's really tricky to get this right, because the
+context in which EXTEND-ENVIRONMENT is called is that MC-APPLY is going to use
+the resulting environment to evaluate the body of the procedure, and we don't
+want to evaluate the body in the case of partial application.  Some of you
+actually managed to work around this problem by modifying EVAL-SEQUENCE as
+well as EXTEND-ENVIRONMENT, something along these lines:
+
+	(define (extend-environment vars vals base-env)
+	  (if (= (length vars) (length vals))
+	      (cons (make-frame vars vals) base-env)
+	      (if (< (length vars) (length vals))
+		  (error "Too many arguments supplied" vars vals)
+		  (MAKE-PROCEDURE ...))))
+
+	(define (eval-sequence exps ENV-OR-PROC)
+	  (cond ((COMPOUND-PROCEDURE? ENV-OR-PROC) ENV-OR-PROC)
+		((last-exp? exps) (mc-eval (first-exp exps) env))
+		(else (mc-eval (first-exp exps) env)
+		      (eval-sequence (rest-exps exps) env))))
+
+but this is an ugly solution.  For one thing, EVAL-SEQUENCE might be used
+someplace other than in MC-APPLY, so we shouldn't change its behavior without
+thinking about those other callers.  But even if the call to EVAL-SEQUENCE in
+MC-APPLY is the only one in the program, it's ugly to have a procedure named
+EVAL-SEQUENCE that sometimes doesn't actually evaluate a sequence!  We
+accepted working solutions on this model, but you shouldn't get in the habit
+of designing this way.
+
+
+Scoring:  There are too many variants to list them all.  We decided to group
+them according to one central issue: do they actually return a procedure?
+
+6  Correct.
+
+5  Correct except for some trivial error.
+
+4  Has the idea: Checks for length mismatch between parameters and arguments,
+   and returns a procedure if there are fewer parameters, but something is
+   wrong with the new procedure's parameters, body, or environment.
+
+2  Has an idea:  Checks for length mismatch, but then returns a lambda
+   expression, an environment, or something else that isn't an MCE procedure
+   (including an STk procedure formed by an underlying-Scheme LAMBDA
+   expression!).
+
+0  Anything else, including modifying only EVAL-SEQUENCE.
diff --git a/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm1/mt1-1.soln.txt b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm1/mt1-1.soln.txt
new file mode 100644
index 0000000..80fa31f
--- /dev/null
+++ b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm1/mt1-1.soln.txt
@@ -0,0 +1,423 @@
+CS 61A          Solutions to sample midterm 1 #1
+
+1.  What will Scheme print?
+
+> (every - (keep number? '(the 1 after 909)))
+(-1 -909)
+
+	The KEEP part of the expression has the value (1 909), selecting the
+	numbers from the given sentence.  (By the way, not everyone recognized
+	this as the name of a Beatles song, from the album _Let It Be_, the
+	last one they released, but the next-to-last one they recorded.)
+
+	(every - '(1 909)) computes (- 1) and (- 909), putting the results in
+	a sentence.  Some people thought this was an error because - requires
+	two arguments, but it doesn't.  With one argument it means negation,
+	rather than subtraction.  (Look it up in the Scheme reference manual
+	at the back of your course reader!)
+
+	A few people said -908, because they thought EVERY would call the
+	function once, giving both numbers as arguments.  That would be
+	(APPLY - '(1 909)), not EVERY.
+
+
+> ((lambda (a b) ((if (< b a) + *) b a)) 4 6)
+24
+
+	Substitute 4 for A and 6 for B in the body of the lambda:
+		((if (< 6 4) + *) 6 4)
+	(< 6 4) is false, so the IF expression returns the multiplication
+	procedure, which is the value of the expression *.  This procedure
+	is then called with 6 and 4 as its arguments.
+
+
+> (word (first '(cat)) (butlast 'dog))
+CATDO
+
+	The wrong answer we expected was CDO, but FIRST of a sentence is its
+	entire first word, even if there's only one word in it.  Another
+	fairly common wrong answer was ERROR, presumably from people who
+	rightly thought that WORD won't accept a sentence as argument, but who
+	didn't see that FIRST of a sentence is a word, which makes it an okay
+	argument to WORD.
+
+	A few people said CATOG because they didn't notice that it was
+	BUTLAST rather than BUTFIRST.  We didn't take off for this.
+
+> (cons (list 1 2) (cons 3 4))
+
+((1 2) 3 . 4)
+
+
+    ---------      ---------
+    |   |   |      |   |   |
+--->| | |  ------->| | | | |
+    | | |   |      | | | | |
+    --|------      --|---|--
+      |              |   |    
+      |              V   V
+      |
+      |              3   4
+      |
+      V
+    ---------      ---------
+    |   |   |      |   |  /|
+    | | |  ------->| | | / |
+    | | |   |      | | |/  |
+    --|------      --|------
+      |              |
+      V              V
+
+      1              2
+
+	There were two important points to this problem: knowing the
+	difference between CONS and LIST, and knowing how Scheme prints
+	improper lists.  (The two upper pairs in the diagram form the
+	spine of an improper list, which is a cdr-linked set of pairs in
+	which the cdr of the last pair isn't the empty list.)
+
+
+> (let ((p (list 4 5)))
+    (cons (cdr p) (cddr p)) )
+
+((5))
+
+        p is bound to (4 5)
+        (cdr p) evaluates to (5), and (cddr p) evaluates to ()
+        (cons '(5) '()) evaluates to ((5))
+
+Box and pointer diagram:
+    +---+---+
+--->| o | / |
+    +-+-+---+
+      |
+      v
+    +---+---+
+    | o | / |
+    +-+-+---+
+      |
+      v
+      5
+
+> (cadadr '((a (b) c) (d (e) f) (g (h) i)))
+(e)
+
+--->X/
+    |
+    V
+    e
+
+	We didn't take off for including other pairs from the large argument
+	in your picture, as long as there was a clear start arrow showing
+	where the return value starts.
+
+	The quickest way to solve this problem is to remember that CADR means
+	the second element, and to view CADADR as (CADR (CADR ...)) -- the
+	second element of the second element of the argument.  Alternatively,
+	we can spell it out step by step:
+
+        (cdr '((a (b) c) (d (e) f) (g (h) i)))  ==>  ((d (e) f) (g (h) i))
+        (car '((d (e) f) (g (h) i)))            ==>  (d (e) f)
+        (cdr '(d (e) f))                        ==>  ((e) f)
+        (car '((e) f))                          ==>  (e)
+
+	The crucial point is to see that it's CAR of CDR of CAR of CDR of the
+	list, which means the first step is CDR -- you have to work from
+	inside out, which in a case like this means from right to left.  If
+	you start by taking the CAR of the big list, you end up with the empty
+	list.
+
+
+
+Scoring: one point each.
+
+
+2.  Order of growth
+
+(define (foo n)
+  (if (< n 2)
+      1
+      (+ (baz (- n 1))
+	 (baz (- n 2)) )))
+
+(define (baz n)
+  (+ n (- n 1)))
+
+FOO is Theta(1).
+
+	Since FOO calls BAZ twice, we have to know the running time of BAZ
+	before we can figure out the running time of FOO.
+
+	BAZ does not contain any recursive calls, either to baz itself or to
+	foo.  Rather, it performs two fixed-time operations, an addition and a
+	subtraction, and so its running time is Theta(1).
+
+	Therefore, everything FOO does is fixed-time!  It calls <, +, -, and
+	BAZ, all of which are Theta(1).  And so FOO itself is also Theta(1).
+
+	The most frequent wrong answer was Theta(2^n).  People who thought
+	that put too much weight on the *form* of procedure FOO.  They saw two
+	procedure calls, and thought that the process was therefore comparable
+	to the Fibonacci computation or the Pascal's Triangle computation.
+	But in those cases, the two calls are *recursive* calls, not calls to
+	a fixed-time helper.
+
+(define (garply n)
+  (if (= n 0)
+      0
+      (+ (factorial n) (garply (- n 1))) ))
+
+(define (factorial n)
+  (if (= n 0)
+      1
+      (* n (factorial (- n 1))) ))
+
+GARPLY is Theta(n^2).
+
+	GARPLY calls itself recursively N times, so it's tempting to think
+	that it's Theta(n), the most common wrong answer.  But each of those N
+	invocations of GARPLY includes an invocation of FACTORIAL, which is
+	itself Theta(n).  So N calls to a Theta(N) procedure makes a total of
+	N*N fixed-time operations.
+
+Scoring: one point each.
+
+
+3.  Normal and applicative order.
+
+The expression (* (counter) (counter)) has the value 2 under both
+applicative and normal order.
+
+Under applicative order, all subexpressions are evaluated before * is called.
+There are two subexpressions of the form (counter), each of which is
+evaluated separately.  The first evaluation returns 1; the second returns 2.
+(It doesn't matter whether they are evaluated left to right or right to
+left, since 1 times 2 = 2 times 1.)
+
+Under normal order, you might think that things would get more complicated,
+but since * is a primitive (as the problem statement says), its arguments
+are evaluated before it is invoked even under normal order.  It's only
+arguments to user-defined procedures that are handled differently.
+
+But even if we did something like this:
+
+	(define (times a b)
+	  (* a b))
+
+	(times (counter) (counter))
+
+it wouldn't change the result.  Normal order *would* affect the call to
+TIMES, so that instead of substituting 1 and 2 for A and B, we'd
+substitute the expression (COUNTER) for both A and B in the body of
+TIMES.  The result of that substitution would be
+
+	(* (counter) (counter))
+
+which is the same thing we started with.
+
+The most common error was to say that the answer would be 1 under applicative
+order.  People who said that were confusing this problem with a different one,
+more like what I did in lecture:
+
+	(define (square x)
+	  (* x x))
+
+	(square (counter))
+
+For *that* problem, the answer would be 1 under applicative order and 2 under
+normal order.  But this is the opposite of the situation you were given.
+Normal order can turn one subexpression into multiple copies (which are then
+separately evaluated), but it can't turn two expressions, even if identical,
+into a single expression to be evaluated once.
+
+Interestingly, almost as many people said that the answer would be 1 under
+*normal* order.  My guess is that they were thinking of the square problem,
+but instead of actually working through that problem, they just remembered
+that normal order is the one that gives the weird answer.  :-)
+
+Scoring: 1 point, all or nothing.
+
+
+4.  Recursive or iterative process?
+
+(define (butfirst-n num stuff)
+  (if (= num 0)
+      stuff
+      (butfirst-n (- num 1) (bf stuff))))
+
+ITERATIVE PROCESS.  The recursive call is the last thing the procedure has
+to do.  (It's inside an IF, but it isn't evaluated until after IF has decided
+which branch to take.)
+
+
+(define (member? thing stuff)
+  (cond ((empty? stuff) #f)
+	((equal? thing (first stuff)) #t)
+	(else (member? thing (bf stuff)))))
+
+ITERATIVE PROCESS.  Again, the recursive call is the last thing the
+procedure has to do.
+
+
+(define (addup nums)
+  (if (empty? nums)
+      0
+      (+ (first nums)
+	 (addup (bf nums)))))
+
+RECURSIVE PROCESS.  The recursive call is the last *line* of the procedure
+definition, but it's inside a call to the + procedure, so the after the
+recursion finishes we still have to call +.
+
+Scoring: one point each.
+
+
+5.  Recursive procedures.
+
+This is the only one that I didn't expect to be immediately obvious
+to all of you.  There are lots of ways to do it.  Here is the one
+suggested by the hint:
+
+(define (syllables wd)
+  (define (chop wd)
+    (cond ((empty? wd) "")
+	  ((vowel? (first wd))
+	   (chop (bf wd)))
+	  (else wd)) )
+  (cond ((empty? wd) 0)
+	((vowel? (first wd)) (+ (syllables (chop wd)) 1))
+	(else (syllables (bf wd))) ))
+
+Another way is to count a vowel only if the next letter isn't one:
+
+(define (syllables wd)
+  (cond ((empty? wd) 0)
+	((vowel? (first wd))
+	 (cond ((empty? (bf wd)) 1)
+	       ((vowel? (first (bf wd))) (syllables (bf wd)))
+	       (else (+ (syllables (bf wd)) 1)) ))
+	(else (syllables (bf wd))) ))
+
+Yet another way is to use a state variable to remember whether
+or not the previous letter was a vowel:
+
+(define (syllables wd)
+  (define (s1 wd was-cons)
+    (cond ((empty? wd) 0)
+	  ((vowel? (first wd)) (+ was-cons (s1 (bf wd) 0)))
+	  (else (s1 (bf wd) 1)) ))
+  (s1 wd 1) )
+
+There were too many kinds of errors to list.  The trick here is
+that the program structure can't be exactly like the examples
+seen earlier, but you have to cope with that while not forgetting
+everything you know about functional programming.  For example,
+many people wanted to keep a count of the number of syllables so
+far in a state variable, so they said things like
+           (if (vowel? (first wd))
+	       (+ count 1)
+	       (... something else ...))
+as if + CHANGED THE VALUE of the variable count.  Thinking in BASIC!
+
+
+6.  Higher order procedures.
+
+(define (in-order? pred sent)
+  (cond ((empty? sent) #t)
+	((empty? (bf sent)) #t)
+	((pred (first sent) (first bf sent))
+	 (in-order? pred (bf sent)) )
+	(else #f) ))
+
+(define (order-checker pred)
+  (lambda (sent) (in-order? pred sent)) )
+
+One common error was to use (in-order? pred (bf (bf sent))) as the
+recursive step, on the theory that the first two elements have already
+been looked at.  The trouble is that you have to compare overlapping
+pairs of elements.  For example, (in-order? < '(2 8 5 9)) should be
+false, even though 2<8 and 5<9, because 8>5.
+
+Scoring: For part (a), three if it's right, two if it's correctly
+typed (that is, your procedure takes a two-argument predicate and
+a sentence as arguments, and returns true or false), one if it has
+some idea, zero if not.  For part (b), two if it's right, one if
+it's correctly typed (takes a predicate function of two arguments
+and returns a predicate function of one argument), zero if not.
+
+
+7.  Time ADT
+
+(define (time-print-form time)
+  (word (hour time) ': (two-digit (minute time)) (category time)))
+
+(define (two-digit num)
+  (if (< num 10)
+      (word 0 num)
+      num))
+
+
+(define (24-hour time)
+  (+ (* (hour time) 100)
+     (minute time)
+     (if (equal? (category time) 'pm) 1200 0)))
+
+
+(define (make-time hr min cat)
+  (+ (* hr 100)
+     min
+     (if (equal? cat 'pm) 1200 0)))
+
+(define (hour time)
+  (if (>= time 1200)
+      (- (div time 100) 12)
+      (div time 100)))
+
+(define (minute time)
+  (remainder time 100))
+
+(define (category time)
+  (if (>= time 1200) 'pm 'am))
+
+
+The most common serious errors were writing a non-function in part (a) and
+rewriting make-time with the wrong number of arguments in part (c).  These
+errors were the ones that gave rise to the most complaints about harsh
+grading, but I really think they're about crucial issues in the course.
+
+Part (a) says, "Write a FUNCTION time-print-form that takes a time as its
+argument and RETURNS a word of the form 3:07pm."  In week 7 of the course
+you should know what it means for a function to return a value!  Some people
+said they were confused by the fact that the word "print" is part of the
+function's name, but a "print form" is the form in which we want things to
+be printed; computing the print form of a time doesn't mean that we should
+actually print it!  Maybe the print form will be used as part of a larger
+sentence that we'll want to print later.
+
+Part (c) says, "Now we decide to change the *internal* representation of
+times to be a number in 24-hour form.  BUT WE WANT THE CONSTRUCTOR AND
+SELECTORS TO HAVE THE SAME INTERFACE SO THAT PROGRAMS USING THE ABSTRACT
+DATA TYPE DON'T HAVE TO CHANGE."  That means that the arguments to make-time
+must be the same things they were all along: an hour (in 12-hour time), a
+minute, and a category (am/pm).
+
+
+Many people returned 3:7pm instead of 3:07pm in part (a), because they
+thought that it would be sufficient to say something like
+        (time-print-form (make-time 3 07 'pm))
+The trouble is that Scheme interprets 07 as the number 7; Scheme doesn't
+remember exactly how you typed the number.  This was a minor error.
+
+Many people, in part (c), changed the internal representation to something
+other than a number, e.g., a list of two numbers.  I've spoken with four
+students who didn't understand why this was wrong, and I asked them to
+read the first sentence of part (c), and they said "... representation of
+times to be in 24-hour form."  And I said, "No, read it again."  On the
+third or fourth try they'd finally read the words "a number."  Sigh.
+
+Typical errors and scores:
+
+4  3:7pm
+3  changes internal form to (15 7) instead of 1507
+2  printing in (a) or wrong args in (c), as above
+1  glimmers of using the abstraction
diff --git a/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm1/mt1-2.pdf b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm1/mt1-2.pdf
new file mode 100644
index 0000000..e7f1e90
--- /dev/null
+++ b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm1/mt1-2.pdf
Binary files differdiff --git a/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm1/mt1-3.pdf b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm1/mt1-3.pdf
new file mode 100644
index 0000000..09e97c3
--- /dev/null
+++ b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm1/mt1-3.pdf
Binary files differdiff --git a/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm2/mt2-1.pdf b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm2/mt2-1.pdf
new file mode 100644
index 0000000..0b90000
--- /dev/null
+++ b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm2/mt2-1.pdf
Binary files differdiff --git a/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm2/mt2-1.soln.txt b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm2/mt2-1.soln.txt
new file mode 100644
index 0000000..e80be44
--- /dev/null
+++ b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm2/mt2-1.soln.txt
@@ -0,0 +1,411 @@
+CS 61A          Solutions to sample midterm 2 #1
+
+1.  What will Scheme print?
+
+Note: Please draw actual boxes, as in the book and the lectures, not XX and X/
+as in these ASCII-art solutions.
+
+Also, please put in the start arrows!  Sometimes it's hard to know where your
+diagrams are supposed to begin, especially if you use leftward and upward
+pointing arrows.
+
+> (map caddr '((2 3 5) (7 11 13) (17 19)))
+ERROR
+
+	(caddr '(2 3 5)) is 5; (caddr '(7 11 13)) is 13.  But (17 19)
+	doesn't have a caddr, which would be the third element of a
+	two-element list.  The error is attempting to take the car of
+	the empty list.
+
+	The most common wrong answer was (5 13), thinking that the error
+	would just slide under the rug.
+
+> (list (cons 2 (cons 3 5)))
+((2 3 . 5))
+
+
+--->X/
+    | 
+    XX--->XX---> 5
+    |     |
+    V     V
+    2     3
+
+	There were two points to note in this problem:  (cons 3 5) creates
+	an improper list, and LIST is called with one argument, making a
+	one-element list (whose spine is the topmost pair in the diagram).
+
+	One error was to think that every call to CONS results in something
+	that prints with a dot, like this: ((2 . (3 . 5)))  But in fact
+	Scheme never prints a dot if the cdr is a pair; if the ultimate
+	pair of a chain of cdr-linked pairs doesn't have the empty list as
+	its cdr, you get the improper list notation (2 3 . 5)
+
+	The extra parentheses in the printed form show that the result is
+	a one-element list whose element is a list structure (in this case,
+	an improper list rather than an actual list).
+
+
+> (append (list '(2) '(3)) (cons '(4) '(5)))
+((2) (3) (4) 5)
+
+
+--->XX--->XX--->XX--->X/
+    |     |     |     |
+    V     V     V     V
+    X/    X/    X/    5
+    |     |     |     
+    V     V     V     
+    2     3     4    
+
+	The most problematic part of this for most students was the CONS.
+	Some people, remembering that the arguments to APPEND must be
+	lists, said that this produced an error -- but of course CONS can
+	produce a list, if its second argument is a list, as it is here.
+	[Fine print: In fact the *last* argument to APPEND is *not* required
+	to be a list, although the others are.  See the Scheme reference
+	manual.]  In this case, the CONS call produces the list ((4) 5).
+	The asymmetry in the handling of (4) and (5) comes from the meaning
+	of CONS in creating a list: the first argument, the car of the new
+	pair, is an *element* of the resulting list, whereas the second
+	argument, the cdr of the new pair, is a *sublist* of the resulting
+	list.  If this confuses you, think about what you'd expect
+			(cons 4 '(5))
+	to do.
+
+	The most common error, still about the CONS call, was to see that
+	it has to do something different from the LIST call, but still
+	try to make it treat its arguments symmetrically, resulting in
+	the wrong answer ((2) (3) 4 5).
+
+
+> (list (cons '(0) '(1)) (append '(2) '(3)))
+(((0) 1) (2 3))
+
+--->XX------------->X/
+    |               |
+    V               V
+    XX--->X/        XX--->X/
+    |     |         |     |
+    V     V         V     V
+    X/    1         2     3
+    |
+    V
+    0
+
+	LIST returns a list with as many elements as it has arguments -- in
+	this case, two elements.  The top two pairs in the diagram are the
+	ones generated by LIST.
+
+	CONS generates exactly one new pair.  In this problem, the first pair
+	on the second line of the diagram is the one generated by CONS.  Its
+	car is the pair on the third line, which is the list (0); its cdr is
+	the second pair on the second line, which is the list (1).  The
+	important thing to see here is that the lists (0) and (1) do not play
+	similar roles in the result, because of the way lists are defined.
+	The car of a pair is a list *element*; the cdr of the same pair is a
+	*sublist*.  So the value returned by the CONS invocation is a list of
+	two elements, namely (0) and 1 -- not (0) and (1); not 0 and 1.
+
+	APPEND strings together the elements of its arguments, so in this
+	case, the result of the APPEND invocation is the list (2 3).
+
+There were two common wrong answers to this part.  One mistake was to put
+the last element of a sublist in the cdr of a pair, like this:
+
+--->XX------------->X/		; WRONG!
+    |               |
+    V               V
+    XX--->1         XX--->3
+    |               |  
+    V               V  
+    X/              2  
+    |
+    V
+    0
+
+The numbers 1 and 3 are attached to the cdrs of their parent pairs,
+rather than to the cars.
+
+The other common mistake was to leave out the pair just above the zero,
+like this:
+
+--->XX------------->X/          ; WRONG!
+    |               |
+    V               V
+    XX--->X/        XX--->X/
+    |     |         |     |
+    V     V         V     V
+    0     1         2     3
+
+A less common, but more serious, error was to leave out part of the
+work by having parentheses in the diagram:
+
+--->XX------------->X/          ; WRONG!
+    |               |
+    V               V
+    XX--->(1)       XX--->(3)
+    |               |
+    V               V
+    (0)             2
+
+There are never any parentheses in a box and pointer diagram.  The
+parentheses in the *printed representation* of a list structure are
+just a notation to represent *pairs* in the actual structure.
+
+
+Scoring:  One point for each printed result; one point for each diagram,
+except for the first part, which got two points or none.
+
+
+2.  Binary search trees
+
+Although the ADT doesn't include empty trees, the program is easier to
+write if you allow for the possibility of getting an empty list as
+argument instead of a tree, because that's what happens when you try to
+recur for the children of a leaf node.  On that assumption, here's one
+way to write it:
+
+(define (all-smaller? tree num)
+  (or (null? tree)
+      (and (< (entry tree) num)
+	   (all-smaller? (left-branch tree) num)
+	   (all-smaller? (right-branch tree) num))))
+
+(define (bst? tree)
+  (or (null? tree)
+      (and (all-smaller? (left-branch tree) (entry tree))
+	   (all-larger? (right-branch tree) (entry tree))
+	   (bst? (left-branch tree))
+	   (bst? (right-branch tree)))))
+
+Most people wrote equivalent programs using COND, which is fine, but I
+find this style cleaner when writing predicates.
+
+A BINARY TREE is just a tree in which each node has at most two
+children.  A BINARY SEARCH TREE is a binary tree with the ordering
+constraints as described in the text.  The text doesn't make that
+entirely clear, because their only use of binary trees is to represent
+the SET ADT, for which a BST is needed.  Therefore, we didn't take off
+points if in part (a) you assumed the ordering relationship and therefore
+only checked the right branch of the tree, as long as you did the tree
+recursion properly in (b).
+
+Scoring:  This and the remaining problems are graded on the scale
+		5    correct
+		3-4  has the idea
+		1-2  has an idea
+		0    other
+
+Having the idea, in this problem, means doing a tree recursion.  The most
+common form of not having the idea was to think, in part (b), that the
+ordering must be checked only with respect to the root node, so you left
+out the recursive calls to BST?.
+
+We took off one point if you violated the binary tree ADT, using CAR and
+CDR instead of ENTRY, LEFT-BRANCH, and RIGHT-BRANCH.  (If you thought
+that those three things are names of trees, rather than of procedures,
+you didn't have the idea.)
+
+A too-common error was to say things like
+	(< (left-branch tree) (entry tree))
+as if the left branch were a number!  It's not; it's a tree.
+
+
+3.  Tree fanout.
+
+The best answer is
+
+(define (max-fanout tree)
+  (accumulate max
+	      (length (children tree))
+	      (map max-fanout (children tree))))
+
+This takes advantage of the fact that ACCUMULATE requires a starting value
+for the accumulation, usually 0 or 1 in the book's examples, but we can use
+the fanout of this node as the starting value.
+
+Here's the non-higher-order, mutual-recursion version:
+
+(define (max-fanout tree)
+  (max (length (children tree))
+       (max-fanout-forest (children tree))))
+
+(define (max-fanout-forest forest)
+  (if (null? forest)
+      0
+      (max (max-fanout (car forest))
+	   (max-fanout-forest (cdr forest)))))
+
+Some people made this more complicated by using a one-element forest as
+the base case in max-fanout-forest, thereby requiring that max-fanout
+check for the special case of a leaf node.  If this were a general
+problem about accumulating the MAX of arbitrary numbers, we couldn't use
+0 as the base case, because all the numbers might be negative, so if
+anything the base case would have to be negative infinity.  But here
+the numbers are node fanouts, and there's no such thing as a negative
+number of children!
+
+Note that max-fanout does not need a base case.  The recursion happens
+either in MAP, for the first solution, or in MAX-FANOUT-FOREST, for
+the second solution.
+
+Having the idea, in this problem, mostly meant understanding the Tree ADT.
+The totally wrong solutions were ones that applied CAR and CDR to a Tree --
+or, equivalently, the ones that said DATUM and CHILDREN but meant CAR and
+CDR.  Note that there is no reference to DATUM in a correct solution to
+this problem!  The fanout has nothing to do with the values in the nodes,
+only with the Tree's shape.
+
+Not only is CAR/CDR recursion a data abstraction violation, it's also a
+fundamental misunderstanding of this particular problem.  It's often the
+case that similar problems could be posed for abstract Trees and for
+list structures viewed as trees.  But if you use CAR/CDR recursion, you
+are thinking of each pair as a node in a binary tree, essentially, so
+the fanout is always 2!  The whole issue of fanout doesn't arise unless
+you have real Trees to think about.
+
+CAR/CDR programs, or their equivalent -- such as programs with expressions
+of the form (not (pair? tree)) -- got at most 2 points, but more often 0 or 1.
+So did programs that confused trees with forests.
+
+Some not-so-bad programs tried to apply MAX to a list of lists of numbers,
+rather than to a list of numbers.  Our general rule was that if we could
+fix your program by replacing a call to MAP with a call to FLATMAP, it
+got 3 points.
+
+A common problem, not so bad, was to get confused about the domain of MAX.
+This procedure takes numbers as arguments, not lists; you can't say
+        (max '(1 2 3 4))
+but you *can* say
+        (apply max '(1 2 3 4))
+or in this case, because all the numbers are positive,
+        (accumulate max 0 '(1 2 3 4))
+The advantage of ACCUMULATE over APPLY is that in some cases, people who
+used APPLY ended up applying MAX to an empty list -- in other words, trying
+to call MAX with no arguments.  That's not allowed, but ACCUMULATE always
+calls MAX with exactly two arguments, if at all, so it doesn't have the
+same potential bug.  All problems in this category lost only one point.
+
+The comments in the solution to question 2 about making unnecessary data
+structures apply here, too.  Several people made trees in which the datum
+of each node was replaced by its fanout.  Others made linear sequences of
+tree nodes.  All of these things only complicate the program; whatever you
+end up doing to create the structure and then process it could instead
+solve the problem directly in one step.
+
+Scoring:  3 or more points for a solution that uses the Tree ADT correctly
+and actually computes fanouts and maximums.  2 or fewer points for a solution
+with car/cdr recursion, tree/forest confusion, nothing about fanouts, or
+nothing about maximum.
+
+
+4.  Data-directed programming.
+
+(define (plus x y)
+  (let ((tx (type x))
+	(ty (type y)))
+    (if (eq? tx ty)
+	(attach-tag tx (+ (contents x) (contents y)))
+	(let ((gxy (get tx ty))
+	      (gyx (get ty tx)))
+	  (cond ((number? gxy)
+		 (attach-tag ty (+ (* gxy (contents x)) (contents y))))
+		((number? gyx)
+		 (attach-tag tx (+ (contents x) (* gyx (contents y)))))
+		(else (error "You can't add apples and oranges.")))))))
+
+
+The use of LET in this solution isn't essential; various rearrangements
+are possible and are equally good.
+
+Surprising numbers of people had trouble understanding what the problem
+was asking for.  They wrote programs in which 3 dynes PLUS 4 centimeters
+equals 12 ergs!  Sorry, 3 plus 4 is not 12 no matter how clever your
+coding style is.  As the problem clearly stated, you were asked to write
+one procedure, the addition procedure, for a larger project that would
+also include a multiplication procedure when completed.  Moral: don't
+be in such a hurry to write code.  Make sure you understand the problem
+you are being asked to solve first!
+
+Another common way to get in trouble was to try to apply the number you
+found in the table (12, in the example) as a procedure.  Just because
+there is an example in the book in which a table contains procedures as
+entries, that doesn't mean that every table has to contain procedures!
+This particular table contains numbers, for units that can be added
+together, and symbols, for units that can be multiplied.
+
+Scoring: 8 points for a perfect solution.
+	 4-7 points for a flawed solution not grossly confused.
+	 2-3 points for a grossly confused but not clueless solution.
+	 0-1 point for a solution showing no understanding at all.
+
+In general we subtracted two points for each flaw, down to the
+minimum for the categories as indicated.  Here are some 2-point errors
+that bottomed at 4 points:
+
+-- not checking the number? predicate
+-- not checking for the arguments being backwards in the table
+-- incorrect conversion formula
+-- violation of the attach-tag data abstraction
+-- wrong args to GET
+
+Here are some errors eligible for the 2-3 point range:
+
+-- checking explicitly for 'ft or 'in
+-- applying a non-procedure
+-- Lisp syntax errors like non-symbol formal parameters
+
+
+5.  OOP
+
+The central point of this question is that in the OOP paradigm, objects are
+used for everything, and the structure of the object classes reflects the
+structure of the real-world situation being simulated.
+
+(a) parenthood
+
+The class VANILLA has the class SCOOP as its parent, because a vanilla scoop
+is a particular kind of scoop.
+
+Is a scoop a special kind of cone?  No.
+
+Is a cone a special kind of scoop?  No.
+
+So the correct answer is "Neither."  Most people got this; the most common
+wrong answer was to say that SCOOP should have CONE as its parent, probably
+because a scoop can be viewed as *part of* a cone.  But the parent/child
+relationship isn't "a part of"; it's "a kind of."
+
+(b) flavors method
+
+(method (flavors)
+  (map (LAMBDA (S) (ASK S 'FLAVOR)) scoops))
+
+You *could* write the CONE class so that its instance variable SCOOPS would be
+a list of flavors (i.e., names of flavors) instead of a list of scoop objects.
+But that wouldn't be following the OOP paradigm.  (Not to mention that using
+the name SCOOPS for a list of flavors would be really confusing!)  So if we
+want to know the flavors in a cone, we have to ask each scoop for its flavor.
+
+A few people said something like (USUAL 'FLAVOR) instead of (ASK S 'FLAVOR),
+presumably because FLAVOR is a method of the SCOOP class, rather than of the
+VANILLA or CHOCOLATE class.  But even if this could work, the whole idea of
+inheritance is that you can send the child class (e.g., VANILLA) the same
+messages you can send to the parent class (SCOOP).  You don't have to know
+whether VANILLA handles the FLAVOR message itself or delegates the message to
+its parent.  And in any case it wouldn't work; USUAL can only be used inside
+a DEFINE-CLASS, because otherwise it doesn't know what object you're talking
+about!
+
+
+(c) adding a scoop
+
+Given a particular ice cream cone, we want to add a particular scoop of
+vanilla ice cream to it -- not the VANILLA class, and not the word VANILLA.
+So the right answer is the last one listed:
+	(ask my-cone 'add-scoop (instantiate vanilla))
+The argument to INSTANTIATE is a class, not the name of a class.
+
+Scoring: 2 points each.  No partial credit except that in part (B) leaving
+out the quotation mark before FLAVOR got one point.
diff --git a/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm2/mt2-2.soln.txt b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm2/mt2-2.soln.txt
new file mode 100644
index 0000000..701905a
--- /dev/null
+++ b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm2/mt2-2.soln.txt
@@ -0,0 +1,609 @@
+CS 61A          Solutions to sample midterm 2 #2
+
+1.  What will Scheme print?
+
+Please put in the start arrows!  Sometimes it's hard to know where your
+diagrams are supposed to begin, especially if you use leftward and upward
+pointing arrows.
+
+> (list (cons 2 3) 4)
+((2 . 3) 4)
+
+          +---+---+     +---+---+
+          |   |   |     |   |  /|
+--------->| | | ------->| | | / |
+          | | |   |     | | |/  |
+          +-|-+---+     +-|-+---+
+            |             | 
+            |             V 
+            |                               
+            |             4
+            |                                  
+            V                                  
+          +---+---+
+          |   |   |
+          | | | | |
+          | | | | |
+          +-|-+-|-+
+            |   |
+            V   V
+
+            2   3
+
+Most people got this.  The ones who didn't most often left out the dot
+in the printed version.
+
+
+> (append (cons '(a) '(b)) '(c))
+((A) B C)
+
+           +---+---+   +---+---+   +---+---+
+           |   |   |   |   |   |   |   |  /|
+---------> | | | ----->| | | ----->| | | / |
+           | | |   |   | | |   |   | | |/  |
+           +-|-+---+   +-|-+---+   +-|-+---+
+             |           |           |
+             |           V           V
+             |
+             |           B           C
+             V
+           +---+---+
+           |   |  /|
+           | | | / |
+           | | |/  |
+           +-|-+---+
+             | 
+             V 
+
+             A 
+
+Many people were confused about this one, especially the CONS part.
+Here is a box and pointer diagram of (cons '(a) '(b)).  The starred
+pair is the one created by the CONS:
+
+
+          ***********
+          *+---+---+*        +---+---+
+          *|   |   |*        |   |  /|
+--------->*| | | ----------->| | | / |
+          *| | |   |*        | | |/  |
+          *+-|-+---+*        +-|-+---+
+          ***|*******          | 
+             |                 V 
+             |                                 
+             |                 B 
+             |                                  
+             V                                  
+	   +---+---+
+	   |   |  /|
+	   | | | / |
+	   | | |/  |
+	   +-|-+---+
+	     | 
+	     V 
+
+	     A 
+
+Even though this structure was created using CONS rather than LIST,
+it's a list, because the cdr of the new pair is a list.  This list
+has two elements; the first is (A) and the second is B.  So in
+effect the call to APPEND is (append '((a) b) '(c)).
+
+We weren't very sympathetic to people who drew diagrams like this:
+
+	   +---+---+
+	   |   |   |
+---------->| | | ------> etc
+	   | | |   |
+	   +-|-+---+
+	     | 
+	     V 
+
+	    (A)
+
+Things in parentheses in the printed representation must be shown
+as pairs in the diagram!
+
+
+
+> (cdadar '((e (f) g) h))
+()
+
+Note that the result is (), not '()!
+
+There really is no need for a box-and-pointer diagram for an empty
+list, which is an atom.  We accepted
+
+	   +---+
+	   |  /|
+---------->| / |
+	   |/  |
+	   +---+
+
+but *NOT* this:
+
+	   +---+---+
+	   |  /|  /|
+---------->| / | / |
+	   |/  |/  |
+	   +---+---+
+
+because that would be a pair, representing the list (()), not an empty list.
+
+Some people got this wrong because they figured the cdadar incorrectly.
+Here's how to get there:
+
+(car '((e (f) g) h))  ===>   (e (f) g)
+(cdr '(e (f) g))      ===>   ((f) g)
+(car '((f) g))        ===>   (f)
+(cdr '(f))            ===>   ()
+
+CDADAR is an abbreviation for (cdr (car (cdr (car ...)))), so you have
+to start at the inside and take the CAR of the argument first.  Some
+people read CDADAR left to right as "take the cdr, then the car, ..."
+but that's wrong.
+
+Scoring:  One point for each, with both printed form and b&p diagram
+correct to get the point.  One point total for people who got all three
+printed results correct but left out the b&p diagrams.
+
+
+
+2.  Fill in the blank.
+
+> (CADADR '(g (h i) j))
+I
+
+
+The letter I is the second element of (H I), so it's
+      (cadr '(h i))
+But the sublist (h i) is the second element of the entire argument,
+so it's
+      (cadr '(g (h i) j))
+So we want
+      (cadr (cadr '(g (h i) j)))
+and that's abbreviated as CADADR.
+
+Scoring: one point, all or nothing!
+
+
+3.  Proj2 data abstraction
+
+(a)  Type-tagged segment ADT.  The solution we wanted was this:
+
+(define (make-segment start end)
+  (attach-tag 'segment (cons start end)))
+
+(define (start-segment seg)
+  (car (contents seg)))
+
+(define (end-segment seg)
+  (cdr (contents seg)))
+
+Alternatively, you could use LIST instead of CONS and CADR instead of CDR.
+
+Here is the crucial point to understand about data abstraction:  WE WANT
+THIS CHANGE NOT TO BREAK EXISTING PROCEDURES IN THE PROJECT!  That means
+that start-segment, for example, must return a vector, just as it did
+before the change.
+
+Some people wrote
+
+(define (start-segment seg)    ;; wrong!!!
+  (attach-tag 'segment (car seg)))
+
+One problem with this is that the start-segment of a segment isn't the
+car of the argument anymore, once we have a type attached.  But it's
+much worse to attach the SEGMENT type to the result, because the result
+isn't a segment!  It's a vector.
+
+Other people gave make-segment only one argument.  Probably this means
+that you don't know what a segment is, because you let your partner do
+all the work on the project.
+
+
+Scoring:
+2  As shown above.
+1  Working code, but not respecting the tagged-data abstraction
+     (e.g., cons instead of attach-tag, cadr and cddr in the selectors).
+0  Anything else.
+
+
+(b) Find the midpoint of a segment or frame.
+
+(define (midpoint shape)
+  (cond ((eq? (type-tag shape) 'segment)
+	 (scale-vect 0.5
+		     (add-vect (start-segment shape)
+			       (end-segment shape))))
+	((eq? (type-tag shape) 'frame)
+	 ((frame-coord-map shape) (make-vect 0.5 0.5)))
+	(else #f)))
+
+We accepted less elegant but correct algorithms for the midpoints of
+the shapes.  For a segment another approach is
+
+         (make-vect (/ (+ (xcor-vect (start-segment shape))
+			  (xcor-vect (end-segment shape)))
+		       2)
+		    (/ (+ (ycor-vect (start-segment shape))
+			  (ycor-vect (end-segment shape)))
+		       2))
+
+For frames we saw two other correct approaches.  One was essentially
+to rewrite frame-coord-map:
+
+         (add-vect (origin-frame shape)
+		   (scale-vect 0.5
+			       (add-vect (edge1-frame shape)
+					 (edge2-frame shape))))
+
+Another was to find the midpoint of a diagonal of the parallelogram:
+
+         (midpoint (make-segment (add-vect (origin-frame shape)
+					   (edge1-frame shape))
+				 (add-vect (origin-frame shape)
+					   (edge2-frame shape))))
+
+Most people had correct algorithms for the midpoint of a segment.  There
+were two common incorrect algorithms for frames; one wrong approach was
+to ignore the frame's origin, and the other was to assume that the frame's
+edge1 contributes only to the x-coordinate of the midpoint and that its
+edge2 contributes only to the y-coordinate.
+
+One reason for incorrect solutions to the midpoint of a frame was that
+people confused the origin of the FRAME with the origin of the COORDINATE
+SYSTEM -- that is, the point (0, 0).  The vector returned by
+(origin-frame shape) points from the coordinate system origin (0, 0) to
+the frame's origin, which is one of its corners.  That corner might or
+might not be at (0,0)!  For example, when you wrote procedures like
+BELOW in the project that combine two pictures in adjacent frames, at
+least one of those frames doesn't begin at (0, 0).
+
+Some people wrote a data-directed solution, including things like
+
+   (put 'frame 'midpoint frame-midpoint)
+
+This was okay, but more work than the problem required.  Other people
+tried to use message passing, with less success.  A correct use of
+message passing means that the data -- the frames and segments -- must
+be represented as procedures:
+
+(define (make-segment start end)
+  (lambda (message)
+     ...))
+
+But this is incompatible with part (a)!  Some people tried to use a
+dispatch procedure for the *operator*:
+
+(define (midpoint shape)   ;; wrong!
+   (lambda (message)
+      ...))
+
+but that doesn't make any sense.  You send messages to objects, not
+to operators.  In general, the way to learn in this course is to focus
+on the IDEAS, not on the SYNTAX.  Don't think:  "Message passing means
+that you say (lambda (message) ...) somewhere."  Instead think:
+"Message passing means that the data objects in the system know how
+to carry out operations on themselves."
+
+
+Some people either didn't read or didn't understand the sample exams
+in the course reader.  Here is a quote from the spring 1995 solutions:
+
+    *** RESPECTING THE DATA ABSTRACTION DOES **NOT** MEAN SAYING "DATUM"
+    *** WHENEVER YOU MEAN CAR, AND "CHILDREN" WHENEVER YOU MEAN CDR!!  That
+    is precisely DISrespecting the data abstraction!  Respecting it means to
+    distinguish between a Tree, whose component parts are called datum and
+    children, and other data types that have other component parts, such as
+    forests (car and cdr, since a forest is just a particular kind of
+    sequence), rational numbers (numer and denom), and so on.
+
+The same thing is true here, except that instead of Trees, this problem
+used tagged data.  RESPECTING THE DATA ABSTRACTION DOES **NOT** MEAN
+SAYING "TYPE-TAG" WHENEVER YOU MEAN CAR, AND "CONTENTS" WHENEVER YOU MEAN CDR!
+That is precisely DISrespecting the data abstraction!  Respecting it means
+to distinguish between a type-tagged datum, whose component parts are
+called type-tag and children, and other data types that have other component
+parts, such as segments, frames, and vectors.
+
+
+Scoring:
+
+3  Correct.
+
+2  The structure of the COND correct, and also
+     (a) both algorithms work, but have data abstraction violations, or
+     (b) one algorithm is correct, and there are no DAVs.
+
+1  At least one working algorithm.
+
+0  Other.
+
+
+4.  Maximum path in Tree
+
+(define (maxpath tree)
+  (if (null? (children tree))
+      (datum tree)
+      (+ (datum tree)
+	 (biggest (map maxpath (children tree))))))
+
+Notice that there is no CAR or CDR in this program!
+
+If you didn't want to use MAP, the equivalent recursive solution is
+
+(define (maxpath tree)
+  (if (null? (children tree))
+      (datum tree)
+      (+ (datum tree)
+	 (maxpath-forest (children tree)))))
+
+(define (maxpath-forest forest)
+  (if (null? (cdr forest))
+      (maxpath (car forest))
+      (max (maxpath (car forest))
+	   (maxpath-forest (cdr forest)))))
+
+This solution does take the CAR and the CDR of a forest (which is
+a sequence of Trees), but still does not apply CAR or CDR to a Tree.
+
+In either case, the algorithm is to find the maxpath of each child,
+take the biggest of those, and add the value at the root.  So, for
+the example in the exam, the maxpath values for the three children
+are 10 (7+3), 11 (2+9), and 10 (4+6).  The biggest of those is 11,
+so we add 5 to that and the overall answer is 16.
+
+It doesn't work to find the largest immediate child of the root
+and work downward from there.  In this example, the largest of the
+children is 7, the first child, but the largest overall path doesn't
+go through that child.
+
+
+PLEASE don't ever try to solve a tree problem iteratively!  Iteration
+is good for sequences of information -- that is, for one-dimensional
+structures.  But tree problems are fundamentally recursive.  A lot of
+solutions had the form
+
+(define (maxpath tree)
+  (maxpath-helper tree (children tree) tree '() '() 0 (datum tree)))
+
+or some similar thing with zillions of extra arguments.  All such
+solutions turned out to be quite wrong, and what's worse, they take
+a long time for us to grade!  :-(
+
+
+Here's another correct solution that some people tried:
+
+(define (maxpath tree)
+  (biggest (maxpath-helper tree)))
+
+(define (maxpath-helper tree)
+  (if (null? (children tree))
+      (LIST (datum tree))
+      (map (lambda (t) (+ (MAXPATH t) (datum tree)))
+	   (children tree))))
+
+Unfortunately, most people who tried this made two mistakes; one was
+to leave out the LIST, using just (datum tree) as the base case, and
+the other was to call maxpath-helper instead of the capitalized
+MAXPATH above.  Both of these errors could be avoided by thinking
+about the domains and ranges of the functions involved:
+
+	function	argument	  return
+
+	biggest		list of numbers	  number
+	maxpath		Tree		  number
+	maxpath-helper	Tree		  list of numbers
+
+Since BIGGEST expects a list as its argument, maxpath-helper
+must return a list, even in the base case.  And since + expects
+numbers as arguments, you can't use maxpath-helper to provide
+one of the arguments to +, because maxpath-helper returns a list.
+
+
+This was apparently the hardest problem, mainly because people don't
+understand the Tree Abstract Data Type.  The two parts of a Tree
+are its DATUM, which is a number, and its CHILDREN, which is a forest,
+that is, a list of Trees.  A list of Trees is not a Tree!  An expression
+such as (maxpath (children tree)) has to be wrong because maxpath
+requires a Tree as its argument, not a list of Trees.
+
+
+Scoring:  There were so many wrong approaches that I can't possibly
+list them all.  The general strategy we tried to follow was
+
+5     correct
+3-4   has the idea
+1-2   has an idea
+0     no idea
+
+Here are a few common cases:
+
+4   correct except for the base case
+3   recursive call to maxpath-helper as described above
+2   (maxpath (children tree))
+2   binary tree ADT (e.g., calls to left-branch and right-branch)
+1   (biggest (children tree)) with no recursion
+
+
+5.  Debugging the broken EVAL-1.
+
+Of the six test cases given, the four that don't give error messages
+give the correct answer; it's the two that say ERROR that are wrong.
+What do those two have in common?  A compound expression -- a procedure
+call -- is used as an argument to another procedure.
+
+(In the first case, the expression (* 2 2) provides an argument to +;
+in the second, the expression (+ 1 1) provides an argument to the
+procedure created by the lambda expression.)
+
+So there's something wrong with the evaluation of argument subexpressions.
+That evaluation of subexpressions happens on line 11.  The correct line is
+
+	(map eval-1 (cdr exp)) ))  ; closing earlier open parentheses
+
+The reason some of the test cases *do* work is that numbers are
+self-evaluating, so using the argument expressions instead of the argument
+values doesn't matter if the argument is just a number.  The student said
+
+	(cdr exp) ))	; This is what you should have in your solution.
+
+leaving out the MAP EVAL-1 part.
+
+The most common error was to say that the error was
+
+	(eval-1 (cdr exp)) ))
+
+omitting just the MAP.  But that would be a disaster; none of the examples
+would have worked.  Take the first test case: (+ 2 3).  If that's EXP,
+then (CDR EXP) is (2 3).  But if we try to EVAL-1 that list, we are asking
+to invoke the procedure 2 with the argument 3!
+
+By the way, the reason the last test case doesn't fail is that IF is a
+special form, so eval-1 never reaches line 11; the subexpressions are
+evaluated on lines 6-8.
+
+Scoring: 5 if correct, 2 if line 11 changed incorrectly, otherwise 0.
+(But in the rare cases where the correct change was attributed to line
+10 or 12, we figured you just misread the line numbers and didn't take
+off points.)  We ignored any explanations you gave, which was a good thing
+in some cases because the explanations were iffy.
+
+
+6.  Data directed programming
+
+I said at least twice in lecture that data-directed programming does NOT
+mean using get and put; the book's example of data-directed programming
+is just one example of a more general idea.  The idea is that instead of
+building the specific details of one problem into our procedures, we
+write more general procedures that use some auxiliary data structure to
+specify the precise problem we're supposed to solve.  In this case, the
+list of transitions ((1 A 2) (1 B 3) ...) is the data structure that
+tells our GENERAL fsm interpreter which SPECIFIC fsm we're using.
+
+To make that clearer, here is a program for the particular fsm used as
+the example in the question, NOT using data-directed programming:
+
+(define (transition state letter)
+  (cond ((= state 1) (state1 letter))
+	((= state 2) (state2 letter))
+	((= state 3) (state3 letter))
+	((= state 4) (state4 letter)) ))
+
+(define (state1 letter)
+  (cond ((eq? letter 'A) 2)
+	((eq? letter 'B) 3)
+	((eq? letter 'C) 4)
+	(else 0) ))
+
+(define (state2 letter)
+  (cond ((eq? letter 'A) 1)
+	(else 0) ))
+
+... and so on for the other two states.  This program has the specific
+transition information built into its procedures.  If you wanted to
+change a transition, you'd have to rewrite some procedure.  Some people
+did in fact offer solutions like this, and got no credit.  Here is the
+solution we had in mind:
+
+(define (transition fsm state letter)
+  (cond ((null? fsm) 0)
+	((and (= state (caar fsm))
+	      (eq? letter (cadar fsm)) )
+	 (caddar fsm) )
+	(else (transition (cdr fsm) state letter)) ))
+
+(define (process fsm state wd)
+  (if (empty? wd)
+      state
+      (process fsm (transition fsm state (first wd)) (bf wd)) ))
+
+This program works not only for the particular fsm diagrammed in the
+question, but for ANY fsm, if we give it the appropriate list of
+transitions as an argument.
+
+For some reason that I don't understand, practically everyone returned
+(cddar fsm) instead of the correct (caddar fsm).  You want the third
+ELEMENT of the transition sublist, not a SUBLIST of the transition sublist.
+But we didn't take off for that.
+
+It's perfectly fine if you want to avoid things like "caddar" (pretty hard
+to work through, isn't it?) by defining an abstract data type for
+transitions.  But please don't think that "data-directed programming"
+MEANS using abstract data types.  The two ideas are quite distinct, even
+though we talked about tagged data during the same week as ddp.  If
+you want to use an abstract data type your program will look like this:
+
+(define start-state car)
+(define arrow-label cadr)
+(define end-state caddr)
+
+(define (transition fsm state letter)
+  (cond ((null? fsm) 0)
+	((and (= state (start-state (car fsm)))
+	      (eq? letter (arrow-label (car fsm)) )
+	 (end-state (car fsm)) )
+	(else (transition (cdr fsm) state letter)) ))
+
+You could also define selectors like first-transition and rest-transitions
+for the fsm list itself, but I wouldn't bother.  Car and cdr are clear
+enough for a sequence of any number of the same kind of thing, such as a
+sequence of transition triples.
+
+But, speaking of data types, it won't work at all to use car and cdr on
+the word we're processing in part B!  Car and cdr only work on pairs
+(and lists, which are made of pairs), not on words.
+
+It would indeed be possible to use GET and PUT to implement a data-directed
+fsm program.  You'd set up the program for a particular fsm by PUTting each
+transition, with the start state and letter as the row and column labels,
+and the end state as the contents of each cell.  This isn't exactly what we
+asked for, but we gave full credit if you did that properly.  But we gave
+no credit at all if you tried to invoke the contents of the cell as a
+procedure!  If you did that, you were just blindly copying the example from
+the book without understanding it.
+
+Scoring:  Having the idea in part A meant using the fsm list to write a
+general program.  No credit if the letters A, B, and C appeared in your
+program (not data directed) nor if you invoked something you found in a
+table (totally off the wall).  Having the idea in part B meant using the
+procedure you wrote in part A!  People who tried to do part B from scratch
+invariably wrote programs that CDRed down the fsm list once, then lost it
+and couldn't process the second letter.  If you got part A completely right
+but totally messed up part B, that was three points.  The other way around
+was two points.  If you partially messed up both parts, we used our
+judgement in accord with the standard five-point formula.
+
+
+7. OOP
+
+(a) Parents and children.  A child class is /a kind of/ the parent class, or
+/a specialization of/ the parent class, /not/ a part or subset of the parent.
+
+Is a keypad a kind of cell phone?  NO, a keypad is part of a cell phone.
+
+Is an office building a kind of building?  YES.
+
+Is a staple a kind of stapler?  NO, it's something you put into a stapler.
+
+Is an arm bone a kind of arm?  NO, it's part of the arm.
+
+Is an arm bone a kind of bone?  YES.
+
+Is an arm bone a kind of person?  NO, it's part of a person.
+
+(b) Class or instance variable.  It's a class variable if it's the same for
+every instance of the class; it's an instance variable if each instance has
+its own value.
+
+The number of taxis in the city isn't different for each taxi; it's a property
+of the entire CLASS of taxis.
+
+The number of milk cartons in a fridge is different for each fridge; mine has
+quite a few because my son and I can't agree about whether to use fat-free
+milk or high-fat (2%) milk, so we get both kinds.  A fridge in a photographic
+studio might be full of film, and have no milk cartons at all.  So the number
+is different for each INSTANCE of the fridge class.
+
+Scoring: 1/2 point each, rounded down to an integer.
diff --git a/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm2/mt2-3.pdf b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm2/mt2-3.pdf
new file mode 100644
index 0000000..47a822a
--- /dev/null
+++ b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm2/mt2-3.pdf
Binary files differdiff --git a/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm3/mt3-1.pdf b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm3/mt3-1.pdf
new file mode 100644
index 0000000..e79cafe
--- /dev/null
+++ b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm3/mt3-1.pdf
Binary files differdiff --git a/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm3/mt3-1.soln.txt b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm3/mt3-1.soln.txt
new file mode 100644
index 0000000..174ff1a
--- /dev/null
+++ b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm3/mt3-1.soln.txt
@@ -0,0 +1,526 @@
+CS 61A		Solutions to sample midterm 3 #1
+
+1.  Box and pointer.
+
+(let ((x (list 1 2 3)))
+   (set-car! x (list 'a 'b 'c))
+   (set-car! (cdar x) 'd)
+   x)
+
+((a d c) 2 3) is printed.
+
+X-->[o|o]-->[o|o]-->[o|/]
+     |       |       |      
+     |       V       V
+     |       2       3      
+     V      
+    (o|o)-->{o|o}-->[o|/]
+     |       |       |      
+     V       V       V      
+     a       d       c 
+
+The result of the first set-car! is ((a b c) 2 3); the second set-car! changes
+the B to D.  (car x) is the pair in (parentheses) in the diagram above, so
+(cdar x) is the pair in {braces}.
+
+
+(define x 3)
+(define m (list x 4 5))
+(set! x 6)
+m
+
+(3 4 5) is printed.
+
+M-->[o|o]-->[o|o]-->[o|/]
+     |       |       |      
+     V       V       V      
+     3       4       5
+
+The point of this example is that once (list x 4 5) has been evaluated, it
+doesn't matter that the 3 came from X; the list contains the values, not the
+expressions that produced the values.  So the list M doesn't "know" that X's
+value is later changed.
+
+
+
+(define x (list 1 '(2 3) 4))
+(define y (cdr x))
+(set-car! y 5)
+x
+
+(1 5 4) is printed.
+
+              Y
+              |
+              |
+              V
+X-->[o|o]-->[o|o]-->[o|/]
+     |       |       |      
+     V       V       V      
+     1       5       4
+
+In this example, Y names the same pair as (cdr x).  So changing the car of Y
+changes the cadr of X, replacing (2 3) with 5.
+
+
+
+(let ((x (list 1 2 3)))
+  (set-cdr! (cdr x) x)
+  x)
+
+(1 2 1 2 1 2 1 2 ...    is printed.
+
+     +---------+
+     |         |
+     V         |
+X-->[o|o]-->[o|o]
+     |       |      
+     V       V      
+     1       2
+
+This example creates a circular list.
+
+
+Scoring: One point per printed representation; one point per diagram.
+
+
+
+2.  Local state.
+
+If we call PREV several times, each of the resulting procedures remembers
+its own previous invocation.  In OOP terminology, PREV represents a class, and
+SLOW-SQUARE is an instance of the class.  So OLD-RESULT should be an instance
+variable.
+
+Of the four choices offered, the first is the one in which OLD-RESULT is an
+instance variable, because the LET happens once per call to PREV, i.e., once
+for each instantiation of the class.
+
+In the second choice, the LET happens only once, when PREV is defined, so
+OLD-RESULT would be a class variable.  In the third choice, the LET happens
+every time an *instance* (such as SLOW-SQUARE) is called, so it's not a state
+variable at all, and SLOW-SQUARE would always return #F.
+
+In the fourth choice, PREV doesn't take an argument!  So that can't be right,
+and you don't even have to look at the LET.
+
+Scoring: 4 points, all or nothing.
+
+
+3.  Environment diagram.
+
+There are four frames (including the global one) and three procedures
+in the diagram.
+
+In the global frame, X is bound to 4, BAZ is bound to procedure P1,
+and FOO is bound to procedure P3.
+
+Frame E1 extends the global environment.  In it, X is bound to 30
+and * is bound to procedure P2.
+
+Frame E2 extends E1.  In it, Y is bound to 8.
+
+Frame E3 extends E1.  In it, A is bound to 30, and B is bound to 8.
+
+Procedure P1 is created in the global environment with parameter X
+and body (define ...) (lambda ...)
+
+Procedure P2 is created in E1 with parameters A and B, and body (+ a b).
+
+Procedure P3 is created in E1 with paremeter Y and body (* x y).
+
+---------
+
+The first expression just adds the X binding to the global environment.
+
+The second expression creates P1 and binds BAZ to it in the global
+environment.
+
+The third expression invokes BAZ, so it creates E1 with X bound to 30.
+[A common error was to bind X to 13, thinking that * means addition
+in the expression (* 3 10).  But procedure P2 hasn't even been created
+yet when (* 3 10) is evaluated, let alone the fact that this expression
+is evaluated in the global environment because it was typed at a Scheme
+prompt.]  Then it evaluates the body of BAZ in environment E1.  This
+creates P2, binds * to it in E1, creates P3, and returns P3 as the
+value from BAZ.  Then FOO is bound to that value, P3, in the global
+environment.
+
+The fourth expression computes (* 2 x) in the global environment,
+getting 8, and creates E2 with Y bound to 8.  [A common mistake was
+to use the value 30, in E1, for X and also use P2 for *, thereby
+computing the value 32 for Y.]  Then, with E2 as the
+current environment, it evaluates the body of FOO, which is (* x y).
+Since E2 is the current environment, and it extends E1, the symbol *
+represents procedure P2 in this expression.  Since this is a
+user-defined procedure, not a primitive, this creates E3 with A
+bound to 30 (the value of X found in E1) and B bound to 8 (the value
+of Y found in E2). Then (+ a b) is evaluated in E3, returning the
+value 38, which is the value of the entire expression.
+
+---------
+
+Scoring of common mistakes:
+
+  3  correct
+
+  2  correct return value 38, but...
+      E3 extends E2
+      E3 variables are named X and Y instead of A and B
+      E3 binds A to "X" instead of 30 and B to "Y"
+      E3 left out altogether
+      P3 right bubble points to E2
+
+  1  X=13 in E1
+     Y=32 in E2
+     E2 extends global environment
+     In E1, "(* a b)" is bound to "(+ x y)"
+     The third expression is interpreted as if it were
+	(define (foo) (baz (* 3 10)))
+      thereby making FOO a procedure of no arguments that calls BAZ
+
+  0  P3's right bubble points to the global frame
+     E1 extends E2 (very strange sequence of events!)
+     Y=30, as if it were
+        (define (baz y) (* x y))
+     extra/missing frames or procedures except as noted earlier
+     several errors
+
+
+4.  List mutation.
+
+The easiest way to do a problem like this is to use a LET in which
+you give names to every relevant piece of the list structure.  Then,
+inside the LET, you can mutate the pairs in any old order without
+risk of error:
+
+(define (make-alist! lst)
+  (if (null? lst)
+      'done
+      (let ((car1 (car lst))
+	    (cdr1 (cdr lst))
+	    (car2 (cadr lst))
+	    (cdr2 (cddr lst)))
+	(set-car! lst cdr1)
+	(set-cdr! lst cdr2)
+	(set-car! cdr1 car1)
+	(set-cdr! cdr1 car2)
+	(make-alist! cdr2)))
+  lst)
+
+But that's more work than is really needed.  If you're clever about
+the order in which you do the mutation, you can get by with only one
+temporary variable.  There are several such solutions; here's one:
+
+(define (make-alist! lst)
+  (if (null? lst)
+      'done
+      (let ((tmp (cddr lst)))
+	(set-cdr! (cdr lst) (cadr lst))
+	(set-car! (cdr lst) (car lst))
+	(set-car! lst (cdr lst))
+	(set-cdr! lst tmp)
+	(make-alist! tmp)))
+  lst)
+
+Both of these solutions use the original first pair as the top-left pair
+of the resulting association list; the original second pair becomes the
+bottom-left pair.  Several people noticed that you can rearrange the
+pairs with no temporary variables at all if you reverse those roles,
+so that what used to be the second pair becomes the head of the new
+association list.  Unfortunately, this isn't quite a correct solution,
+because the caller of MAKE-ALIST! probably has some variable that still
+has the original first pair as its value, so the caller will think that
+that first pair is the new a-list.
+
+Neither of these solutions uses the value returned by recursive calls.
+It's also possible to write a solution that does:
+
+(define (make-alist! lst)
+  (if (null? lst)
+      'done
+      (let ((tmp (make-alist! (cddr lst))))
+	(set-cdr! (cdr lst) (cadr lst))
+	(set-car! (cdr lst) (car lst))
+	(set-car! lst (cdr lst))
+	(set-cdr! lst tmp)))
+  lst)
+
+Note that you must check (NULL? LST) *before* you try to take its
+CAR or CDR.
+
+Scoring of typical solutions:
+
+4  OK
+3  Bad/missing base case;
+   rearranges by mutation but the order isn't quite right;
+   leaves second pair on top;
+   uses return value from recursive call but doesn't return a value.
+2  No temporary variable (via LET or helper procedure).
+1  Uses CONS (or LIST or APPEND, etc).
+0  (set! (car lst) ...) or similar confusions.
+
+Solutions using CONS scored lower than other errors because the problem
+explicitly said not to allocate new pairs.  It's important that you 
+understand the difference between allocating a pair and making a new
+pointer to an already-existing pair.  Although it's true that the old
+pairs would be reclaimed, so the total storage requirement of the program
+wouldn't increase with solutions using CONS, sometimes it's important not
+to allow a delay for garbage collection.  For example, if your program is
+creating video animation in real time, a garbage collection might bring
+the animation to a halt for a substantial time, perhaps half a second.
+
+
+5.  Vectors.
+
+To solve this problem it's important to understand what it's about.  The
+result (histogram) vector is separate from the argument (scores) vector; the
+two vectors have different sizes; there is no simple correspondence between
+one element of the result and one element of the argument.  Each element of
+the result depends on examining *every* element of the argument.  The kind of
+higher order function strategy that we often use for lists is not appropriate
+in this problem.
+
+Having passed that hurdle, there is an insight about algorithms that helps
+to simplify the solution if you see it:  Although each element of the result
+depends on every element of the argument, each element of the *argument*
+contributes to *only one* element of the result.  Therefore, a solution that
+works by iterating through the elements of the argument can run in Theta(N)
+time, whereas a solution that iterates through the elements of the result
+will require Theta(N^2) time, and more complicated code.
+
+Here is the Theta(N) solution:
+
+(define (histogram scores)
+  (define (help result i)
+    (if (< i 0)
+	result
+	(begin (vector-set! result
+			    (vector-ref scores i)
+			    (+ (vector-ref result (vector-ref scores i)) 1))
+	       (help result (- i 1)))))
+  (help (make-vector (+ (vector-max scores) 1) 0)
+	(- (vector-length scores) 1)))
+
+It's important that the call to MAKE-VECTOR initializes every element of the
+histogram vector to zero, because we're going to be adding to those values in
+the HELP loop.
+
+You might find it easier to read this slight variant:
+
+(define (histogram scores)
+  (define (help result i)
+    (if (< i 0)
+	result
+	(let ((score (vector-ref scores i)))
+	  (vector-set! result
+		       score
+		       (+ (vector-ref result score) 1))
+	  (help result (- i 1)))))
+  (help (make-vector (+ (vector-max scores) 1) 0)
+	(- (vector-length scores) 1)))
+
+Here's the Theta(N^2) version:
+
+(define (histogram scores)
+  (define (count-score score total j)
+    (cond ((< j 0) total)
+	  ((= (vector-ref scores j) score)
+	   (count-score score (+ total 1) (- j 1)))
+	  (else
+	   (count-score score total (- j 1)))))
+  (define (help result i)
+    (if (< i 0)
+	result
+	(begin (vector-set! result
+			    i
+			    (count-score i 0 (- (vector-length scores) 1)))
+	       (help result (- i 1)))))
+  (help (make-vector (+ (vector-max scores) 1))
+	(vector-max scores)))
+
+And, yes, instead of writing COUNT-SCORE as above, you could use
+(VECTOR-LENGTH (VECTOR-FILTER ...)) to find the count of students with a
+given score.  But that would be pretty inefficient (although only by a
+constant factor), because VECTOR-FILTER examines every element of the
+argument vector twice, and creates a new vector, which you use only long
+enough to count its elements, then throw it away.  VECTOR-FILTER makes a good
+homework problem, but it's not something you would ever really want to use in
+vector-based programming.
+
+It's possible to use the Theta(N^2) algorithm with only one helper procedure,
+instead of two, by having the helper take two index arguments, one for each
+vector.  But it's really, really hard to get that right, and even if you do,
+it's really, really hard for anyone else (or you, next week) to read the
+resulting program.
+
+
+The first index in a vector is 0; the last is (- (vector-length vec) 1).
+Many people lost a point by trying
+	(vector-ref vec (vector-length vec))
+
+People found many ways to make the problem more complicated than necessary,
+such as using
+	(define (helper i)
+	  ...
+	  (set! i (+ i 1))
+	  (helper i)...)
+instead of
+	(define (helper i)
+	  ...
+	  (helper (+ i 1))...)
+This isn't incorrect, but at this late stage in the semester it shows an iffy
+understanding of recursion.
+
+The only two places you can use DEFINE are at the Scheme prompt or at the
+beginning of a procedure body.  You can't, for example, say
+	(cond (some-test
+	       (define ...)
+	       ...)
+	 ...)
+
+
+Scoring:
+
+7  correct.
+
+6  off-by-one error in calculating vector length or end test.
+
+5  in Theta(N) algorithm, doesn't initialize result elements to zero.
+5  computes vector correctly but doesn't return it.
+5  right logic, but a Scheme language error (e.g., misplaced DEFINE).
+
+4  (VECTOR-REF RESULT INDEX) instead of
+   (VECTOR-REF RESULT (VECTOR-REF SCORES INDEX)).
+
+2  No allocation of new vector (result overwrites argument).
+
+0  Uses lists, or takes car/cdr of a vector.
+
+There were other, less common errors; generally "has the idea" got 5, while
+"has an idea" got 2.
+
+
+6.  Parallelism in real life.
+
+For this question we got several essays trying to justify solutions other
+than the obvious ones.  For the most part we didn't accept these -- the
+problem did say "the answer which BEST describes..." -- with one exception
+noted in part (b) below.
+
+(a) People at tables can't get food; people waiting for food can't get
+tables.  This is a potential deadlock, and that was the answer we wanted.
+It's true that the deadlock might not happen, because some people at
+tables may actually have food and might eventually leave, letting the line
+continue moving.  It depends partly on whether the restaurant servers
+believe you when you say "it's okay to serve me because my friend is already
+sitting at a table and saving me a seat."  Even if they do, a deadlock can
+happen if someone comes in alone (so doesn't have a friend to grab a table)
+and when that person gets to the front of the line, all the tables are filled
+with friends of people behind him/her in line.
+
+You may think "it's UNFAIR for people who don't have food yet to hog the
+tables" or "it's INEFFICIENT for people to sit at tables when they don't
+have food yet."  But these are technical terms about parallellism errors,
+and the particular situation described in the problem is technically a
+deadlock.
+
+(b) There are several inspectors serving several lines in parallel, but
+there's only one metal detector, which acts as a single serializer for
+all the inspectors.  This is inefficiency (too much serialization).
+
+Some people argued that the metal detector is best viewed as an actual
+resource, not as a serializer, and so this is correct, if unfortunate,
+serialization of a shared resource.  We accepted that reasoning, so we
+also accepted "none of the above" as a correct answer.
+
+(c) You write while your friend researches.  This is correct parallelism,
+with two processors carrying out parallelizable tasks.
+
+Some people argued that the tasks *aren't* correctly parallellizable
+because the research has to come before the writing.  That idea has some
+merit for a short paper, but you wouldn't be writing a short paper as a
+team anyway; it'd be an individual assignment.  We meant that you were
+writing one part of the paper while your friend was researching a different
+part of the paper.
+
+Some people said "unfairness" because you have to do the boring writing
+while your friend is off doing the interesting research.  One of the
+nice things about working in groups is that sometimes you're lucky and
+your interests complement those of your friend!  But even if you would
+feel an unfairness in this arrangement, it's not unfair in the technical
+sense -- a parallelism unfairness would be if the librarians always get
+books for your friend before they get books for you.
+
+Scoring: One point each.
+
+
+7.  Streams.
+
+The easiest solution is in two steps:  First we make a stream of all possible
+strings of {\tt OVER} and {\tt UNDER}, and then we filter out the ones that
+don't satisfy the condition of having at least one of each:
+
+(define foo
+  (cons-stream '()
+               (interleave (stream-map (lambda (p) (cons 'over p)) foo)
+                           (stream-map (lambda (p) (cons 'under p)) foo))))
+
+(define patterns
+  (stream-filter (lambda (p) (and (member 'over p) (member 'under p)))
+                 foo))
+
+You can't combine these two steps; several people tried this:
+
+(define patterns     ;;; wrong!
+  (stream-filter (lambda ...)
+                 (cons-stream '() (interleave (stream-map ... patterns)
+                                              (stream-map ... patterns)))))
+
+The trouble is that this process will never get started, because the two calls
+to stream-map can only operate on patterns that have previously been
+generated, and there won't be any of those until something makes it through
+the filter.  As a result, the variable PATTERNS hasn't been defined when the
+calls to stream-map try to use it.
+
+Another wrong solution was to try to avoid the need for filtering by "priming
+the pump" with initial patterns other than the empty one, like this:
+
+(define patterns         ;;; wrong!
+  (cons-stream '(over under)
+     (cons-stream '(under over)
+        (interleave ...))))
+
+This indeed gets started correctly, and generates only legal patterns,
+but it doesn't generate all of them.  In particular, it won't generate
+the example shown in the problem:
+
+    (over over under over under under)
+
+because this pattern, although legal, doesn't end with OVER UNDER or
+UNDER OVER.
+
+Some people, recognizing the problem with that last solution, tried to
+get around it by adding words both front and back.  That might possibly
+work, but the people who tried it wanted to add words at the end with
+             (cons p 'over)
+which of course doesn't make a valid list.
+
+Another intriguing method involved the use of random numbers to make
+a randomly chosen pattern for each element of the stream.  It can be
+argued that if the random number generator has perfectly well-distributed
+results, this approach will eventually generate any desired pattern.
+(And, since the number of already-generated patterns is finite, and
+the number of not-yet-generated patterns is infinite, the probability
+of duplication of patterns is zero!  Alas, this doesn't mean it can't
+happen.  :-)  But we didn't accept these solutions because part of the
+idea in an infinte stream is that you have to be able to guarantee that
+any particular element is reachable in bounded time.
+
+
+Scoring:  We graded this one very leniently:
+
+3  correct
+2  interleave correct, filtering missing or incorrect
+1  interleave wrong, but a good try
+0  not close
diff --git a/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm3/mt3-2.soln.txt b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm3/mt3-2.soln.txt
new file mode 100644
index 0000000..759cb3b
--- /dev/null
+++ b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm3/mt3-2.soln.txt
@@ -0,0 +1,484 @@
+CS 61A		Solutions to sample midterm 3 #2
+
+1.  Box and pointer.
+
+(let ((x (list 1 2 3)))
+  (set-cdr! (car x) 4)
+  x)
+
+prints: *** Error:
+    set-cdr!: wrong type of argument: 1
+
+(CAR X) is 1, not a pair, so it has no cdr to mutate.
+
+
+(let ((x (list 1 2 3)))
+  (set-cdr! x 4)
+  x)
+
+(1 . 4) is printed.
+
+X-->[o|o]--> 4      
+     |      
+     V      
+     1 
+
+Since we are changing the list's cdr to a non-pair, it becomes a "dotted pair."
+
+
+(let ((x (list 1 2 3)))
+  (set-car! (cdr x) x)
+  x)
+
+(1 (1 (1 (1 (1 ...   is printed.
+
+
+      +------+
+      |      |
+      V      |
+X-->[o|o]-->[o|o]-->[o|/]
+     |               |      
+     V               V      
+     1               3
+
+The list's second element is replaced with the list itself, making a circular
+list.  3 is still the third element, but the print procedure never reaches it.
+
+
+(define a ((lambda (z) (cons z z)) (list 'a)))
+(set-cdr! (car a) '(b))
+a
+
+((a b) a b) is printed.
+
+A-->[o|o]
+     | | 
+     | |
+     | |    
+     | |    
+     V V    
+    {o|o}-->[o|/]
+     |       |      
+     V       V      
+     a       b 
+
+Note that the two arrows downward from the first pair point to the same place!
+An arrow to a pair points to the entire pair, not just to its car or its cdr.
+(By contrast, an arrow *from* a pair *does* come from one half of the pair,
+not from the entire pair.)
+
+The pair in {braces} is the one whose cdr is changed (from being the empty
+list) by the set-cdr! invocation.
+
+
+Scoring: One point per printed representation; one point per diagram.
+
+
+
+2.  Assignment, state.
+
+(define (make-player room)
+  (lambda (message)
+    (set! room (next-room room message))
+    room))
+
+That's it!  There's no need to check for specific messages such as South,
+since next-room will take care of that for you.
+
+Scoring:
+
+4  correct
+3  sets room correctly but doesn't return it
+2  domain and range of make-player and of the lambda correct, but
+   something's wrong with setting room.
+1  room is set, but no lambda
+0  even worse
+
+
+3.  Environment diagram.
+
+
+First of all, in this problem there are two procedures created:
+
+P1: parameters X and F, body (IF ...)
+
+P2: parameter Y, body (+ X Y)
+
+
+There are also four environment frames:
+
+G: the global frame
+
+E1: has X bound to 3, F bound to #F
+
+E2: has X bound to 5, F bound to procedure P2
+
+E3: has Y bound to 7
+
+
+Solutions not satisfying the above generally got no points.
+
+The hard part is how to hook these up.  When FOO is defined, a binding
+for FOO is made in the global environment.  Also, the global environment
+is current when the (outer) LAMBDA expression is evaluated, so FOO is P1
+and P1's right bubble points to G.
+
+By the way, that first expression could have been written as
+
+        (define (foo x f) ...)
+
+with exactly the same meaning.
+
+That's all that happens when the first expression is evaluated.
+Procedure P2 and frames E1 through E3 are all created during the
+evaluation of the second expression.
+
+First we call FOO with arguments 3 and #F.  This creates frame E1,
+which extends G, because G is what P1's right bubble points to.
+
+Now we evaluate the body of P1 (a/k/a FOO), using E1 as the current
+environment.  The body is the IF expression.  F is false, so we must
+evaluate (FOO 5 (LAMBDA ...)).
+
+To evaluate a procedure call we first evaluate all the subexpressions.
+In particular, the inner LAMBDA expression is evaluated at this time,
+with E1 as the current environment.  Therefore, P2's right bubble
+points to E1.
+
+Once we've evaluated the subexpressions, we create a new frame, E2,
+binding FOO's parameters to these new arguments.  So in E2 the value
+of X is 5, and the value of F is procedure P2.  Note that this
+binding for F is in E2, but the procedure to which F is bound was
+created in E1.  That's really important, and many groups missed it.
+
+What environment does E2 extend?  Since we are calling P1 (a/k/a FOO),
+we extend the environment in P1's right bubble, namely G.  This, too,
+is a really important point.  If you had E2 extend E1, you are using
+dynamic scope, not lexical scope, which is correct for Scheme.
+
+We now evaluate the body of P1, the IF expression, with E2 current.
+The value of F is true in this environment (since anything other than
+#F is considered true), so we now evaluate (F 7).
+
+To do that, we make a frame, E3, in which Y is bound to 7.  What environment
+does E3 extend?  The procedure we're calling, P2, was created in E1, so E3
+must extend E1 -- not E2, even though that's the current environment.
+
+Since E3 extends E1, the relevant value of X is 3, and so the answer
+that Scheme prints is 10, which is 3+7.
+
+The most common wrong answer was 12, which is 5+7.  (Only a handful of
+papers had any answer other than 10 or 12.)  As it turns out, there were
+two ways of getting the answer 12, with different scores:
+
+  * Many groups thought that procedure P2 was created in environment E2,
+    and so E3 would extend E2 even following the lexical scope rule.
+    This was a relatively mild error, getting 2 points.
+
+  * Many other groups used dynamic scope, getting 1 point.  You were
+    deemed to be using dynamic scope if E3 extended E2 even though P2's
+    right bubble pointed to E1.  You were also deemed to be using
+    dynamic scope if E3 extended E2, and E2 extended E1, regardless of
+    where P2 pointed.
+
+    (A few papers had E2 extending E1, but E3 correctly extending E1,
+    the diagram otherwise correct, and an answer of 10.  These groups
+    were not deemed to be believers in dynamic scope, but merely
+    careless, getting 2 points.)
+
+Several groups got the answer 10 despite incorrect diagrams.  This was a
+surprise, but it turned out that they did it by mixing the substitution
+model with the environment model.  (Since the expressions in the problem
+did not involve mutation, the substitution model does yield the right
+value for (FOO 3 #F) even though it's not what Scheme really does.)
+More specifically, these solutions had (+ 3 Y) instead of (+ X Y) as the
+body of P2.  Such papers got 1 point.
+
+Some papers had P2's right bubble pointing to E3, a frame that didn't
+even exist when P2 was created.  We don't understand what those groups
+were thinking.
+
+Another zero-point solution was to have bindings to expressions rather
+than to values.  For example, some papers had a binding in E2 of the form
+
+	F: (lambda (y) (+ x y))
+
+It's really important to understand that Scheme's job is to translate
+expressions into values, and that only values get into environments.
+(This is what it means to say that Scheme uses applicative order
+evaluation, rather than normal order.)
+
+Scoring:
+
+3  OK
+2  lexical scope, but some error
+1  dynamic scope, or substitution model
+0  gibberish, extra frames, expressions in environments
+
+
+4.  List mutation.
+
+We were surprised at how hard you found this problem.  The solution
+we wanted is pretty short and simple:
+
+(define (merge! a b)
+  (cond ((null? a) b)
+	((null? b) a)
+	((<= (car a) (car b))
+	 (set-cdr! a (merge! (cdr a) b))
+	 a)
+	(else
+	 (set-cdr! b (merge! a (cdr b)))
+	 b)))
+
+This solution DEPENDS CRITICALLY on the fact that merge! RETURNS A VALUE.
+Most of you got in trouble by forgetting to return a value.
+
+The easiest way to think about this problem may be to start by writing
+a functional (non-mutating) version:
+
+(define (merge a b)        ; Not a solution to the exam problem!
+  (cond ((null? a) b)
+	((null? b) a)
+	((<= (car a) (car b))
+	 (cons (car a) (merge (cdr a) b)))
+	(else
+	 (cons (car b) (merge a (cdr b))))))
+
+There's a stream version of this procedure in the book, and in any case
+you should find it easy to invent this.  The mutating version has the
+SAME STRUCTURE, but instead of calling CONS it has to mutate an
+existing pair, and separately return a value.
+
+One of the most important ideas you can learn is the mathematical
+concept of SYMMETRY.  In this case, what that means is that you should
+notice that merge! treats its two arguments equivalently; if you
+interchanged the order of the arguments you should still get the same
+answer.  Therefore, your program should be symmetrical as well; anything
+you do to A should be done in the same way to B.  Many people used
+asymmetrical kludges, and therefore had incredibly long programs that
+didn't work.
+
+Another good idea to learn is QUIZMANSHIP.  Some time around your
+11th or 12th cond clause, you ought to stop and think, "They wouldn't
+assign something this complicated on an exam."  (This is quite
+different from the sort of quizmanship in which you try to guess at
+answers based on irrelevant factors.)
+
+Several solutions had cond clauses with complicated conditions such as
+    (and (< (car a) (car b)) (> (car a) (cadr b)))
+There are a few situations in which you really do have to use this
+degree of complexity, but they're rare.  Really what this means is
+that you're not trusting the recursion to do its job with the second
+elements of the lists.
+
+Several solutions rearranged things in a way that would work only if
+the second-smallest number is in the other list from the smallest
+number.  That is, you hook the two cars together and then recursively
+deal with the two cdrs.  Think about a case like
+   (merge! (list 1 2 3) (list 4 5 6))
+In this example the result should be the same as if you'd appended
+the lists, not the same as if you interleaved them.
+
+A few people did append the lists, and then sort them by insertion
+sort or bubble sort or some such thing.  This can work, and we
+gave full credit for working solutions of this kind, but you should
+be aware that it makes the problem take O(n^2) time instead of
+O(n), and it's more complicated to write correctly, too!  By
+appending the two lists you're losing the valuable information
+that each of them is already ordered.
+
+In a problem about lists, you have to remember that the car and
+the cdr of a pair do NOT play symmetrical roles in the representation
+of a list.  Each car is an element; each cdr is a sublist.  In a
+list of numbers, each car is a number; no cdr is a number.  Therefore,
+any solution that interchanges cars and cdrs or tries to mutate a
+car of something just can't be right:
+   (set-car! (car x) ...)
+   (set-cdr! (car x) ...)
+   (set-cdr! x (car y))
+   (set-car! x (cdr y))
+For solutions of this sort we subtracted three points from what
+the score would otherwise be.
+
+Grading:
+7  correct
+6  base case error
+5  no return value, but it only matters to the ultimate caller
+4  no return value, and so the recursion doesn't work
+4  rearranges pairs with set-cdr! but incorrectly
+3
+2  uses set-car! to rearrange pairs.  (Some set-car! solutions are correct.)
+1
+0  allocates pairs (calls CONS, LIST, APPEND, etc.)
+0  uses set! to rearrange pairs.  (Some uses of set! are okay, but they
+                                    never actually help the solution.)
+
+Then subtract 3 points for the cases mentioned in the previous paragraph.
+
+
+5.  Vectors.
+
+There are many ways to do this, but they all share two essential points:
+First, there must be a helper procedure that recursively moves through the
+vector, changing one element at a time; second, there must be some way to
+remember one element (generally the original last element) of the vector,
+either through a LET or through an extra argument to the helper.
+
+Here's a straightforward solution:
+
+(define (rotate! v)
+
+  (define (help i)
+    (if (= i 0)
+	'this-value-doesnt-matter
+	(begin (vector-set! v i (vector-ref v (- i 1)))
+	       (help (- i 1)))))
+
+  (let ((temp (vector-ref v (- (vector-length v) 1))))
+    (help (- (vector-length v) 1))
+    (vector-set! v 0 temp)
+    v))
+
+The last line (with just the V) is there so that ROTATE! returns the vector,
+since the return value from VECTOR-SET! is unspecified.
+
+The elements of a vector of N elements are numbered from 0 to N-1, not from
+1 to N.  That's why the expression (- (VECTOR-LENGTH V) 1) is used to find
+the index of the rightmost element.
+
+It's very important that this program starts at the right end and works
+down to the left end, so that if we are given (A B C D) to rotate, the
+intermediate results are
+	(a b c d)
+	(a b c c)
+	(a b b c)
+	(a a b c)
+	(d a b c)
+If we started at the left end instead, we'd get
+	(a b c d)
+	(a a c d)
+	(a a a d)
+	(a a a a)  ; maybe stop here, or
+	(d a a a)  ; maybe something like this.
+There are other ways to organize the program so that left-to-right operation
+does produce the desired result.  Here's one that works from left to right,
+always swapping the chosen element with the last element:
+
+(define (rotate! v)
+
+  (define (swap v i j)
+    (let ((temp (vector-ref v i)))
+      (vector-set! v i (vector-ref v j))
+      (vector-set! v j temp)))
+
+  (define (help i)
+    (if (< i (vector-length v))
+	(begin (swap v i (- (vector-length v) 1))
+	       (help (+ i 1)))))
+
+  (help 0)
+  v)
+
+When we ran across this solution in the grading, it took us some time to
+convince ourselves that it really works.  Here's a trace of intermediate
+results:
+	(a b c d)
+	(d b c a)
+	(d a c b)
+	(d a b c)
+	(d a b c)
+
+The problem told you to mutate the given vector, not create a new one.
+That rules out any call to MAKE-VECTOR, either directly or through a
+helper procedure such as VECTOR-COPY; it also rules out things like
+	(list->vector (list-rotate (vector->list v)))
+
+A few students recognized that they should use a LET to save something,
+but instead of saving one element, tried to save the entire vector with
+something along the lines of
+	(let ((new-v v)) ...)
+If this did what they intended, it would be ruled out by the problem
+statement, but in fact it does *not* make a copy of the vector.  It just
+makes a new variable that's bound to the same (as in EQ?, not EQUAL?)
+vector as the original variable V.
+
+
+Scoring:
+
+7  correct.
+
+6  indexing off by one (1 to N instead of 0 to N-1).
+   vector rotated, but not returned.
+
+4  one element lost (no LET or equivalent).
+   new vector allocated, but no VECTOR->LIST or LIST->VECTOR.
+   no base case in recursive helper.
+   one value propagated by shifting left-to-right.
+
+2  LIST->VECTOR etc.
+   no recursion (just two values swapped).
+   other messed up reorderings (such as reversal).
+
+0  Total misunderstanding of vectors, such as (CAR V).
+
+We did not assign scores 1, 3, or 5.
+
+
+6.  Concurrency.
+
+(a)  The only possible value is 10.  If the first process runs first,
+it sets BAZ to 5, and then the second process sets it back to 10.  If the
+second process runs first, it sets BAZ to 20, and then the first process
+sets it back to 10.
+
+(b)	5: P1 computes baz/2 = 5, then P2 runs completely, then P1 stores 5.
+	10: either correct sequential order
+	15: P2 loads BAZ once from memory (getting 10), then P1 runs
+		completely (setting BAZ to 5), then P2 loads BAZ again
+		(getting 5), adds 10+5, stores 15.
+	20: P2 computes baz+baz = 20, then P1 runs completely, then
+		P2 stores 20.
+
+
+Scoring:
+
+3  correct
+2  (a) correct, (b) missing one value and no wrong ones added
+1  (a) correct or (b) correct
+0  neither correct
+
+
+7.  Streams.
+
+(define stream-car car)       ; unchanged from the stream-only version
+
+(define (stream-cdr sl)
+  (if (procedure? (cdr sl))   ; or PROMISE?
+      (force (cdr sl))
+      (cdr sl) ))
+
+;;;;;;;; or
+
+(define (stream-cdr sl)
+  (if (or (pair? (cdr sl)) (null? (cdr l)))
+      (cdr sl)
+      (force (cdr sl)) ))
+
+Scoring: 1 point for stream-car, 3 for stream-cdr.  Part credit in the latter
+for any attempt that shows understanding of the need to distinguish the two
+cases, especially if it's clear that what needs to be distinguished is the
+nature of the cdr rather than of the entire argument.
+
+Comment: Many of you seem to be upset because you never heard of the
+predicate PROCEDURE? and therefore couldn't figure out how to do the
+test.  I'm unsympathetic to this problem, for several reasons:
+
+        1.  You came across PROCEDURE? in the adventure game project,
+        where it is used in the version of PERSON? that you rewrote.
+
+        2.  You own a copy of the Scheme reference manual, which has
+        a perfectly good index.
+
+        3.  If you couldn't think of PROCEDURE? you could have used
+        PAIR? or ATOM? or LIST? to distinguish the two cases.
diff --git a/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm3/mt3-3.soln.txt b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm3/mt3-3.soln.txt
new file mode 100644
index 0000000..20db87b
--- /dev/null
+++ b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Midterm3/mt3-3.soln.txt
@@ -0,0 +1,459 @@
+CS 61A		Solutions to sample midterm 3 #3
+
+1.  Box and pointer.
+
+(let ((x (list 1 2 3)))
+  (set-cdr! (cdr x) (cddr x))
+  x)
+
+(1 2 3) is printed.
+
+X-->[o|o]-->[o|o]==>[o|/]
+     |       |       |      
+     V       V       V      
+     1       2       3
+
+In this example the SET-CDR! call effectively does nothing, since it
+replaces the cdr of (cdr x) with the cddr -- the cdr of the cdr -- of X.
+The arrow drawn with = instead of - above is the one that's replaced with
+itself.
+
+
+(let ((x (list 1 2 3)))
+  (set-car! x (cddr x))
+  x)
+
+((3) 2 3) is printed.
+
+     +----------------+
+     |                |
+     |                V
+X-->[o|o]-->[o|o]-->[o|/]
+             |       |      
+             V       V      
+             2       3
+
+The set-car! invocation changes (car x), i.e., the first element of X.
+It's changed to (cddr x), which is a *sublist*, not just an element, of X.
+Thus the new first element is not 3, but (3).
+
+
+
+(let ((x (list 1 2 3)))
+  (set-car! (cdr x) (cdr x))
+  x)
+(1 ((((((((( ...  is printed.
+
+             +-+
+             | |
+             | V
+X-->[o|o]-->[o|o]-->[o|/]
+     |               |      
+     V               V      
+     1               3 
+
+Note that the arrow at the top of the diagram points *from the car* of the
+second pair, but points *to the entire pair* (because that's how pointers
+always work), not just to the cdr, even though that's where the arrowhead
+happens to be.
+
+There's still a 3 in this list, but it'll never be printed.
+
+
+
+(let ((x (list 1 2 3 4)))
+  (set-cdr! (cddr x) (cadr x))
+  x)
+
+(1 2 3 . 2) is printed.
+
+X-->[o|o]-->[o|o]-->[o|o]--> 2      
+     |       |       |      
+     V       V       V      
+     1       2       3
+
+In this example we change the cdr of a pair (because we're doing SET-CDR!) to
+point to a non-pair, (CADR X), the second element of X, which is 2.  Thus the
+result is an improper list, so there's a dot in the printed version.
+
+It doesn't matter, in the diagram, whether you have two 2s, as above, or have
+two arrows pointing to the same 2.  It *does* matter when the thing being
+pointed to is a pair; then there's a big difference between two pointer to the
+same pair, and two pairs that have the same values in them.
+
+
+Scoring: One point per printed representation; one point per diagram.
+
+
+2.  Local state.
+
+Does Louis's MEMOIZE give wrong answers?  YES.
+
+Explanation:  It has one table shared among all memoized functions,
+instead of a separate table per function.
+
+Example:
+
+[Louis has defined MEMO-FIB, as shown in the question.]
+
+> (memo-fib 4)
+3
+> (define memo-square (memoize (lambda (x) (* x x))))
+> (memo-square 4)
+3
+
+Since MEMO-FIB and MEMO-SQUARE share the same table, (memo-square 4)
+returns the value previously remembered from (memo-fib 4).
+
+Some students who checked NO explained why the answer is really YES, so
+we figured people misread the question, and went by your explanantion
+rather than by which choice you checked.
+
+Pretty much any explanation with a phrase like "a single table" or
+"universal table" or "global table" was accepted.  (It's not quite right
+to say "a table in the global environment"; the table is actually a local
+state variable of MEMOIZE.)
+
+Explanations that merely restate the form of Louis's change to the program
+were not accepted:  "The program gives wrong answers because Louis has moved
+the LET to outside of the LAMBDA."  You had to explain what *effect* that
+would have on the program's *behavior*.
+
+The example didn't necessarily have to take the form of a specific Scheme
+interaction as above, but did have to assert that two different functions are
+memoized.
+
+Scoring:
+
+4  correct
+2  correct explanation, no/bad example;
+   iffy explanation (like "global environment" discussed above)
+0  bad explanation (including saying that it doesn't give wrong answers)
+
+No odd scores were assigned.
+
+
+3.  Environment diagram.
+
+Bindings A=8 and B=9 go in the global environment.
+
+Then comes the LET, which is equivalent to an invocation of the procedure
+generated by an implicit LAMBDA:
+
+	((lambda (a f) (f 5))
+	 3
+	 (lambda (b) (+ a b)))
+
+As with any procedure invocation, **first all the subexpressions are
+evaluated!**  This evaluation takes place in the global environment -- we
+haven't invoked any procedures yet.
+
+Thus, two procedures are created whose right bubbles point to the global
+environment.  Only then do we invoke the (lambda (a f) ...) procedure, which
+creates a frame in which A is bound to 3, and F is bound to the
+(lambda (b) ...) procedure.  That new frame, of course, extends the global
+environment.
+
+With that frame as (the first frame of) the current environment, we can
+evaluate the body of the LET, which is (F 5).  We find a binding for F in
+the current environment; it's the (lambda (b) ...) procedure.  So we can
+invoke that with the argument 5.
+
+Since F's right bubble points to the global environment, that's what we
+extend with the new frame that binds B=5.  So when we evaluate F's body,
+which is (+ A B), we find the bindings A=8 and B=5.
+
+Thus, the final answer is 13.
+
+
+The overwhelmingly most common mistake was to think that the (lambda (b) ...)
+procedure's right bubble points to the A=3 frame, so the B=5 frame points
+there also, and the final value is 8.  You should know, though, that a LET
+binding can't depend on another binding in the same LET; for example, if the
+problem had been
+
+	(let ((a 3)
+	      (c (+ a b)))
+	  (+ a c))
+
+I hope most people would have known that C would be 8+9, using the global
+bindings for both A and B.  The fact that the computation using A happens
+inside a lambda body doesn't change the fact that the LET's binding for A
+isn't available to it.
+
+A few people drew the environment diagram that would give an answer of 8,
+but instead wrote 13 as their final answer, which means either that they
+copied someone else's final answer or that they *do* know how Scheme
+evaluates expressions, but don't make any connection between that and
+the environment model.  We graded this as if they'd said 8.
+
+A couple of people had procedure F's right bubble correctly pointing to the
+global environment, but nevertheless had the B=5 frame extending the A=3
+frame, using dynamic scope instead of lexical scope.  This gave the same
+wrong final answer of 8.
+
+Scoring:
+
+6  correct.
+3  answer was (or should have been) 8, as discussed above.
+0  even worse (too many frames, no arrows at all -- there weren't many).
+
+
+4.  List mutation
+
+(define a (list 'x))
+(define b (list 'x))
+(define c (cons a b))
+(define d (cons a b)) 
+
+(eq? a b)                    => #F
+
+	Each call to LIST generates new pairs (one new pair, in this case,
+	because each list has only one element).
+
+(eq? (car a) (car b))        => #T
+
+	Both CARs are the symbol X, and equal symbols are always EQ.
+
+(eq? (cdr a) (cdr b))        => #T
+
+	Both CDRs are the empty list, and there's only one empty list.
+
+(eq? c d)                    => #F
+
+	Each call to CONS generates a new pair.
+
+(eq? (cdr c) (cdr d))        => #T
+
+	Both CDRs are the pair named B -- the same pair.
+
+(define p a)
+(set-car! p 'squeegee)
+(eq? p a)                    => #T
+
+	P and A are two names for the same pair.  Mutating the pair
+	doesn't change the variable bindings.
+
+(define q a)
+(set-cdr! a q)
+(eq? q a)                    => #T
+
+	This one looks trickier because the pair now points to itself,
+	but it's really the same as the previous question: Q and A are
+	two names for the same pair.
+
+(define r a)
+(set! r 'squeegee)
+(eq? r a)                    => #F
+
+	This time we didn't mutate a pair; we changed the binding of
+	one of the variables.  So R and A now name two different things;
+	A is still a pair, but R is now a symbol.
+
+Score: 1/2 point each, rounded down to the nearest whole point.
+
+
+5.  Vector programming
+
+(define (ssort! vec)
+  (define (help start)
+    (if (= start (vector-length vec))
+	vec
+	(let ((smallest (subvec-min-start vec start)))
+	  (let ((temp (vector-ref vec smallest)))
+	    (vector-set! vec smallest (vector-ref vec start))
+	    (vector-set! vec start temp)
+	    (help (+ start 1))))))
+  (help 0))
+
+The key point to understand is that you need to walk through the vector,
+bringing the smallest element out to position 0, then the next-smallest to
+position 1, and so on, until you run out of elements.  Thus we have a helper
+procedure with an argument, START, whose value is the position that we're
+up to in the vector; it starts at 0 and is increased by 1 on each recursive
+invocation.
+
+The next important point is that you can't exchange two elements without
+using a temporary variable to remember one of them, hence the LET that
+creates the variable TEMP.  There are two nested LETs because the value of
+SMALLEST is needed to find the value of TEMP in this solution; I could have
+simplified things a little by remembering the other value in the swap instead:
+
+(define (ssort! vec)
+  (define (help start)
+    (if (= start (vector-length vec))
+	vec
+	(let ((smallest (subvec-min-start vec start))
+	      (temp (vector-ref vec start)))
+	  (vector-set! vec start (vector-ref vec smallest))
+	  (vector-set! vec smallest temp)
+	  (help (+ start 1))))))
+  (help 0))
+
+Scoring:
+
+6  correct
+5  trivial error (e.g. base case off by one)
+3  right structure, gets swap wrong
+2  serious algorithm confusion
+0  allocates new vector, uses lists, or incoherent
+
+
+6.  Concurrency
+
+(define (make-mutex)
+  (let ((in-use #f)
+	(s (make-serializer)))
+    (define (the-mutex m)
+      (cond ((eq? m 'acquire)
+	     (if ((s (lambda ()
+		       (if in-use
+			   #t
+			   (begin (set! in-use #t)
+				  #f)))))
+		 (the-mutex 'acquire)))     ; retry
+	    ((eq? m 'release)
+	     (set! in-use #f))))
+    the-mutex))
+
+The structure of the above is just like that of the MAKE-MUTEX in the book,
+except that when an atomic test-and-set operation is needed, it's done by
+including the (IF IN-USE ...) and the (SET! IN-USE #T) within the same
+serialized procedure, rather than by relying on a TEST-AND-SET! primitive.
+
+Many people found the problem deeply confusing.  You learned that
+serialization has three levels of abstraction: the hardware support,
+the critical section mechanism (mutex) based on the hardware, and
+the more abstract level in which procedures are protected rather than
+sequences of instructions.  So what does it mean to define a mutex
+in terms of a serializer?  But actually this could happen.  Suppose
+you are using a language such as Java, with high-level serialization
+built in (and presumably implemented using hardware support), to write
+an operating system that is supposed to provide a mutex capability to
+its users.  You would then write something equivalent to what this
+problem asks for.  What defines an abstraction is its behavior, not
+how it's implemented -- this is the whole idea behind abstraction.
+
+The SICP version uses (LET ((CELL (LIST FALSE))) ...) because their
+TEST-AND-SET! tests and modifies a pair, not a variable, mainly so that
+it can be an ordinary procedure rather than a special form.  In this
+version there's no need to use a pair, although it wouldn't be wrong.
+
+The ugly (IF ((S (LAMBDA () ...))) ...) is necessary because of the way
+serializers work: they take a procedure as argument and return a protected
+version of that procedure, which must then actually be invoked.
+We didn't take off for minor failures in the notation, accepting even
+solutions in which the argument to the serializer was an expression to
+be evaluated atomically: (IF (S (IF IN-USE ...)) ...)  But we didn't
+accept solutions in which the serializer was given data, rather than
+activity, as its argument.  (More on that below.)
+
+The reason for the nested IFs is a little subtle; the recursive call
+to THE-MUTEX to retry the operation if it fails can't be inside the
+serialized procedure, because then it'll block waiting for S, which is
+held by this process itself -- in effect, setting up a deadlock within a
+single process.  But we didn't take off points for missing this subtlety.
+
+Some people used a single global serializer instead of a separate one
+for each mutex.  At first we considered this a serious error, because
+it means that two mutexes can't be acquired at the same time.  But then
+we realized that the serializer just protects the acquiring of the mutex,
+not the critical section that the mutex itself protects, so any mutex
+holds the serializer only for a very short time.  So we allowed a global
+serializer, except in papers that also missed the point in the previous
+paragraph.  If a mutex can get into a deadlock with itself, while holding
+a serializer needed by all the other mutexes, that's serious enough to
+lose a point.
+
+Some solutions never actually tested whether the mutex was in use before
+acquiring it.  Presumably those people thought that the serializer would
+protect the entire critical section, not just the acquiring, so that if
+an acquire operation could get into the serializer the mutex must be free.
+But that's not the case; the mutex returns to its caller once it has
+set its in-use flag, so the caller's critical section is *not* keeping the
+serializer busy.  Such solutions got at most one point.
+
+There were a few common zero-point solutions.  The strangest were the
+ones that called parallel-execute.  The job of a mutex is to protect
+critical sections against other processes, not to create other processes.
+
+Another zero-point solution had expressions such as (S CELL) that showed
+a lack of understanding of the key fact that a serializer protects
+activities, not data.  Similarly, no points for anything that included
+
+        (something . args)       ;; pfui
+
+which indicated mindless copying from the MAKE-SERIALIZER in the book
+without understanding.  Serializers accept as arguments procedures with
+any number of arguments, but any particular use of a serializer isn't
+going to be that complicated -- and none of these solutions found any
+use for the ARGS variable anyway.
+
+Scoring:
+3  OK
+2  at least an atomic test-and-set implementation
+1  no test-and-set, but some idea
+0  way off
+
+
+7.  Streams.
+
+The answer we expected was
+
+(define all-integers
+  (cons-stream 0 (interleave integers
+                             (scale-stream -1 integers))))
+
+The stream generated by this expression looks like this:
+
+        0, 1, -1, 2, -2, 3, -3, 4, -4, ...
+
+You had to understand two key points to get this solution:
+
+1.  You can't have all the integers in size order.  A stream must have
+a definite first element!  There's no smallest negative integer.  Some
+people tried to REVERSE the stream of integers; that's meaningless.
+
+2.  You can't APPEND-STREAMS two infinite streams.  This is explained
+in the handout you got in lecture.  Since the first stream will never
+finish, it's as if the second stream isn't there at all!  (A few people
+used MERGE, which works for two sorted, increasing streams, but not
+in a case like this where one stream is growing up and one growing down.)
+
+There were many other correct solutions, most of which essentially
+reinvented INTERLEAVE.  Special mention for the following beautiful
+solution (which the student unfortunately didn't get quite right):
+
+(define zeros-ones (cons-stream 0 (cons-stream 1 zeros-ones)))
+
+(define all-integers (subtract-streams zeros-ones
+                                       (cons-stream 0 all-integers)))
+
+where subtract-streams is like add-streams with the obvious difference.
+Work this out to convince yourself that it really works!
+
+Scoring:
+
+4  correct
+3  small mistakes, like leaving out zero
+2  append-stream etc.
+1  stream of streams, like (cons-stream negatives positives)
+0  not a stream at all
+
+We heard from several students who thought that the stream-of-streams
+solution was graded too harshly.  Here's the reasoning behind this
+grading policy:  Most errors come from uncertainty about how to
+implement an infinite stream successfully.  But this error indicates
+a misunderstanding about what the stream abstraction is for!  Think
+about the example of testing whether a number is prime.  We create
+a stream containing a range of numbers (range 2 14) and then we use
+that as an argument to FILTER:
+        (filter (lambda (number) (= (remainder 15 number) 0))
+                (range 2 14))
+
+If RANGE returned a stream of streams, then this FILTER wouldn't
+work, because the elements of the stream wouldn't be numbers!  So,
+even though the problem said "a stream containing all the integers"
+instead of "a stream containing all the integers, in which each
+element is a single integer," it's unreasonable to think that a
+stream whose elements aren't numbers would be acceptable.
diff --git a/js/games/nluqo.github.io/~bh/61a-pages/Volume2/OOP/belowline.pdf b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/OOP/belowline.pdf
new file mode 100644
index 0000000..5458cba
--- /dev/null
+++ b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/OOP/belowline.pdf
Binary files differdiff --git a/js/games/nluqo.github.io/~bh/61a-pages/Volume2/OOP/ref-man.pdf b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/OOP/ref-man.pdf
new file mode 100644
index 0000000..05aec70
--- /dev/null
+++ b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/OOP/ref-man.pdf
Binary files differdiff --git a/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Therac-25.pdf b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Therac-25.pdf
new file mode 100644
index 0000000..cbd6860
--- /dev/null
+++ b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/Therac-25.pdf
Binary files differdiff --git a/js/games/nluqo.github.io/~bh/61a-pages/Volume2/mapreduce-osdi04.pdf b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/mapreduce-osdi04.pdf
new file mode 100644
index 0000000..fce8825
--- /dev/null
+++ b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/mapreduce-osdi04.pdf
Binary files differdiff --git a/js/games/nluqo.github.io/~bh/61a-pages/Volume2/quick.pdf b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/quick.pdf
new file mode 100644
index 0000000..b91e5f7
--- /dev/null
+++ b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/quick.pdf
Binary files differdiff --git a/js/games/nluqo.github.io/~bh/61a-pages/Volume2/r5rs.pdf b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/r5rs.pdf
new file mode 100644
index 0000000..7cce72d
--- /dev/null
+++ b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/r5rs.pdf
Binary files differdiff --git a/js/games/nluqo.github.io/~bh/61a-pages/Volume2/sicp-errata.txt b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/sicp-errata.txt
new file mode 100644
index 0000000..1467159
--- /dev/null
+++ b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/sicp-errata.txt
@@ -0,0 +1,56 @@
+
+
+
+
+   Errata for Structure and Interpretion of Computer Programs 2nd
+   edition
+     ________________________________________________________________
+   
+     Positive line numbers count from the top of the page or exercise,
+     negative line numbers count from the bottom.
+     
+     Page 45, line -13:   Exponent should be n/2, not b/2
+     
+     Page 112, line 2 of exercise 2.30:   Square-LIST should be
+     square-TREE. ("That is, square-tree should behave as follows:")
+     
+     Page 118, lines 1-2:   Should say "...the product OF THE SQUARES
+     of the odd integers..."
+     
+     Page 176, before procedures rectangular? and polar?:   Should say
+     "rectangular and polar numbers, respectively"
+     
+     Page 181, line -5:   Should not refer to exercise 3.24, just to
+     section 3.3.3.
+     
+     Page 185, exercise 2.73a:   Should ask about VARIABLE?, not
+     SAME-VARIABLE?
+     
+     Pages 246 and 247, figures 3.7 and 3.8:   There is an extra ')' at
+     the end of the code.
+     
+     Page 287, figure 3.28:   Rightmost box should have +, not *
+     
+     Page 324, exercise 3.50:   Should refer to section 2.2.1, not
+     2.2.3.
+     
+     Page 341, line 3 of exercise 3.66:   Should say "For example,
+     APPROXIMATELY how many pairs..."
+     
+     Page 375, line 1 of exercise 4.7:   Last LET should be LET*
+     ("...bindings of the let* variables...")
+     
+     Last updated 08/09/99
+     
+
+
+
+
+
+
+
+
+
+
+
+				374
diff --git a/js/games/nluqo.github.io/~bh/61a-pages/Volume2/word.txt b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/word.txt
new file mode 100644
index 0000000..e47aa23
--- /dev/null
+++ b/js/games/nluqo.github.io/~bh/61a-pages/Volume2/word.txt
@@ -0,0 +1,121 @@
+
+    WORD AND SENTENCE MANIPULATION PROCEDURES
+
+    The first chapter of the textbook deals exclusively with numeric data.
+    To allow some variety, with interesting examples that aren't about
+    calculus, we are going to use some additional Scheme procedures that
+    manipulate linguistic data: words and sentences.  A word can be
+    considered as a string of characters, such as letters and digits.
+    (Numbers can be treated as words.)  A sentence is a string of words
+    in parentheses.
+
+
+    PROCEDURES TO TAKE APART WORDS AND SENTENCES:
+
+    FIRST	    returns the first character of a word, or
+		    the first word of a sentence
+
+    BUTFIRST	    returns all but the first character of a word,
+		    or all but the first word of a sentence
+
+    BF		    same as BUTFIRST
+
+    LAST	    returns the last character of a word, or
+		    the last word of a sentence
+
+    BUTLAST	    returns all but the last character of a word,
+		    or all but the last word of a sentence
+
+    BL		    same as BUTLAST
+
+    Examples:
+
+    > (first 'hello)
+    h
+
+    > (butlast '(symbolic data are fun))
+    (symbolic data are)
+
+
+    PROCEDURES TO COMBINE WORDS AND SENTENCES
+
+    WORD	    arguments must be words; returns the word with
+		    all the arguments strung together
+
+    SENTENCE	    returns the sentence with all the arguments
+		    (words or sentences) strung together
+
+    SE		same as SENTENCE
+
+    Examples:
+
+    > (word 'now 'here)
+    nowhere
+
+    > (se 'lisp '(is cool))
+    (lisp is cool)
+
+
+
+					    375
+
+
+
+
+
+
+
+					    
+
+
+    PREDICATE PROCEDURES
+
+    EQUAL?	    returns true if its two arguments are the same word
+		    or the same sentence (a one-word sentence is not
+		    equal to the word inside it)
+
+    MEMBER?	    returns true if the first argument is a member of
+		    the second; the members of a word are its letters
+		    and the members of a sentence are its words
+
+    EMPTY?	    returns true if the argument is either the empty
+		    word [which can be represented as "" ] or the
+		    empty sentence [which can be represented as '() ]
+
+
+
+    MISCELLANEOUS
+
+    COUNT	    returns the number of letters in the argument word, or
+		    the number of words in the argument sentence.
+
+    ITEM	    takes two arguments: a positive integer N, and a word or
+		    sentence; returns the Nth letter of the word, or the Nth
+		    word of the sentence (counting from 1).
+
+
+
+    Examples:
+
+    (define (buzz n)
+      (cond ((member? 7 n) 'buzz)
+	    ((= (remainder n 7) 0) 'buzz)
+	    (else n) ))
+
+    (define (plural wd)
+      (if (equal? (last wd) 'y)
+	  (word (bl wd) 'ies)
+	  (word wd 's) ))
+
+
+
+
+
+
+
+
+
+
+
+
+					    376