CS 3 Midterm 1 solutions Spring 1994 1. What will Scheme print? > (item (- 5 3) (* 8 9)) 2 This is equivalent to (item 2 72), which asks for the second "letter" of the word 72. > (keep (lambda (x) (member? 'a x)) '(eight days a week)) (DAYS A) This asks to keep those words that contain the letter "a". We were fussy about the parentheses. > (first (first (butfirst (butfirst '(fool on the hill))))) T Not (T), just a word! Here's how to figure it out: (bf '(fool on the hill)) --> (on the hill) (bf '(on the hill)) --> (the hill) (first '(the hill)) --> the (first 'the) --> t > (member? 'b (or 'red 'blue)) #F This was the hardest one. The worst error was to say #T because you thought that the expression is English, and means "is the letter 'b' a member of 'red' or 'blue'?" Scheme isn't English! We were a little more sympathetic with people who said "error" because OR is a predicate and you can't use #T or #F as the second argument to MEMBER?. But if you read p. 77 again, you'll see that OR is a semipredicate, and in fact the value of the expression (or 'red 'blue) is RED. So the whole thing really means (member? 'b 'red) which is false. > (every 'square '(4 5 6)) ERROR As most of you noticed, the quoted word 'SQUARE is different from the procedure SQUARE. > (lambda (rin go) (word rin go)) PROCEDURE This was an easy one; LAMBDA returns a procedure, period. Scoring: 1/2 point each, rounded down, except that if your only mistake was to say "error" for the MEMBER? one we gave full credit. 2. Domain and range of EVERY. EVERY takes two arguments. The first must be a procedure whose domain includes words and whose range is words and/or sentences. The second must be a word or sentence. The range of EVERY is sentences. Scoring: 2 points if correct. We didn't take off if your description of the first (procedure) argument was incomplete, as long as you didn't actually say anything false. 1 point if you thought the second argument had to be a sentence, if you left out the range, or if you thought the range includes words. No points for anything worse than that. Some people said that the first argument mustn't be a predicate. That's true, but incomplete; for example, it also mustn't return a procedure. Far too many people said "EVERY takes two arguments. The second argument is a sentence, but the first is something new: a procedure used as an argument to another procedure." I'm flattered that you chose to quote my writing, but I'd feel more confident about your understanding of what you wrote if you didn't seem to think that "something new" is a technical term! And if you'd read on to the next page, you would have seen "You can also use a word as the second argument to EVERY." 3. Wacko and Yakko. Wacko is right; this expression results in an error. It's not relevant that IF is a special form. What matters, in this problem, is that STRANGE is *not* a special form, so when you invoke it, Scheme follows its usual rule: First it evaluates all the subexpressions, then it invokes the procedure. So Scheme tries to compute (/ 7 0) before it ever has a chance to notice that the body of STRANGE includes a call to IF. Yakko would be right if the question asked about a direct invocation of IF, such as (if (> 11 3) (+ 11 1) (* 2 (/ 7 0))). But that's not how Scheme works. Scoring: 2 points for the right answer and a good reason. 1 point for the right answer and a dubious reason. No points if you said Yakko or if your reason for choosing Wacko was clearly irrelevant. An honorary American Cultures credit to the student who said, "Dot, because she's cute." (By the way, I know it's really spelled "Wakko," but I thought it would be less confusing if the two names looked less similar.) 4. Long-word. The answer we were expecting was (define (long-word sent) (accumulate max (every count sent))) Another correct answer was (define (long-word sent) (count (accumulate (lambda (a b) (if (> (count a) (count b)) a b)) sent))) However, it's *not* correct to say (define (long-word sent) ;; wrong (accumulate (lambda (a b) (max (count a) (count b))) sent)) because after the first time, one of the arguments to the function generated by the lambda will be a number instead of the word that you're expecting. (We gave this solution 3 points.) A lot of people said, instead of (every count sent), (every (lambda (wd) (count wd)) sent) which is perfectly correct, but unnecessary. What were you thinking? Several people defined COUNT. That's also correct but unnecessary. All of the procedures listed on the inside back cover of the text are provided for you; you may use them without defining them. One popular error was (max (every count sent)), leaving out the accumulate. MAX takes numbers as arguments, not a sentence. Scoring: 4 points if correct. 3 points for no accumulate. 2 points for (every count sent) with no max, or for KEEP instead of ACCUMULATE, or for no COUNT. 1 point for worse than that, and no points for not even close. 5. keeper. (define (keeper kept) (lambda (wd) (keep (lambda (ltr) (member? ltr wd)) kept)) Several people ended up with formal parameters like SENT because you mindlessly copied one of the solutions from one of the sample midterms. There aren't any sentences in this problem. We didn't take off for bad variable names, but the resulting procedures were never correct anyway. Scoring: There were many ways to get this wrong, not all of which are listed here. But the common ones were (3 points) mixing up the arguments I've called KEPT and WD; (2 points) getting all three arguments mixed up, no inner lambda, or an EVERY thrown in; (1 point) no outer lambda, or the wrong number of arguments to some procedure; (0 points) having the specific example about vowels built into the solution.