Fundamentals of CS I (CS151 2002F)

Exam 2: Higher-Order Scheme

Distributed: Friday, November 8, 2002
Due: Friday, November 15, 2002
No extensions.

This page may be found online at


Useful Files


There are five problems on the exam. Some problems have subproblems. Each full problem is worth twenty points. The point value associated with a problem does not necessarily correspond to the complexity of the problem or the time required to solve the problem.

This examination is open book, open notes, open mind, open computer, open Web. However, it is closed person. That means you should not talk to other people about the exam. Other than that limitation, you should feel free to use all reasonable resources available to you. As always, you are expected to turn in your own work. If you find ideas in a book or on the Web, be sure to cite them appropriately.

Although you may use the Web for this exam, you may not post your answers to this examination on the Web (at least not until after I return exams to you). And, in case it's not clear, you may not ask others (in person, via email, by posting a please help message, or by any other means) to put answers on the Web.

This is a take-home examination. You may use any time or times you deem appropriate to complete the exam, provided you return it to me by the due date. It is likely to take you about five to ten hours, depending on how well you've learned topics and how fast you work. I would appreciate it if you would write down the amount of time each problem takes. I expect that someone who has mastered the material and works at a moderate rate should have little trouble completing the exam in a reasonable amount of time. Since I worry about the amount of time my exams take, I will give three points of extra credit to the first two people who honestly report that they've spent at least eight hours on the exam or who note that they've completed the exam in under eight hours. (At that point, I may then change the exam.)

You must include both of the following statements on the cover sheet of the examination. Please sign and date each statement. Note that the statements must be true; if you are unable to sign either statement, please talk to me at your earliest convenience. Note also that inappropriate assistance is assistance from (or to) anyone other than myself or our teaching assistant.

1. I have neither received nor given inappropriate assistance on this examination.
2. I am aware of no other students who have given or received inappropriate assistance on this examination.

Because different students may be taking the exam at different times, you are not permitted to discuss the exam with anyone until after I have returned it. If you must say something about the exam, you are allowed to say This is among the hardest exams I have ever taken. If you don't start it early, you will have no chance of finishing the exam. You may also summarize these policies. You may not tell other students which problems you've finished.

You must both answer all of your questions electronically and turn them in in hardcopy. That is, you must write all of your answers on the computer, print them out, and hand me the printed copy. You must write your name on the top of every page of the printed exam. You must also email me a copy of your exam by copying your exam and pasting it into an email message. Put your answers in the same order as the problems. Make sure that your solution confirms to the format for laboratory writeups

In many problems, I ask you to write code. Unless I specify otherwise in a problem, you should write working code and include examples that show that you've tested the code.

Unless I specify otherwise, you should fully document all of the primary procedures (including parameters, purpose, value produced, preconditions, and postconditions). If you write helper procedures (and you may certainly write helper procedures) you should document those, too, although you may opt to write less documentation. When appropriate, you should include short comments within your code. You should also take care to format your code carefully. If you write down the amount of time you spend on each problem, I'll give you three points of extra credit.

Just as you should be careful and precise when you write code, so should you be careful and precise when you write prose. Please check your spelling and grammar. I am likely to penalize you for bad spelling and grammar.

I will give partial credit for partially correct answers. You ensure the best possible grade for yourself by emphasizing your answer and including a clear set of work that you used to derive the answer.

I may not be available at the time you take the exam. If you feel that a question is badly worded or impossible to answer, note the problem you have observed and attempt to reword the question in such a way that it is answerable. If it's a reasonable hour (before 10 p.m. and after 8 a.m.), feel free to try to call me in the office (269-4410) or at home (236-7445).

I will also reserve time at the start of classes this week and next to discuss any general questions you have on the exam.


Problem 1: Restricting Values

Gary and Gwen Gimper have been having lots of fun writing interesting image filters to use with gsfu-map-image and gsfu-create-image. However, they don't like using mod to restrict a value to the range [0..255]. They say

While we understand the need to restrict the value to the range [0..255] and we like the ease of using mod, we don't like the abrupt transition between nearby numbers. That is, the jump from 255 (lots of a color) to 255+1 mod 256 = 0 (none of that color) is very severe. We'd like a procedure like mod, except that it's more continuous. In particular, that new procedure, which we'd like to call restrict-255, should return 254 when given 256 as a parameter, 253 when given 257 as a parameter, and so on and so forth. Of course, when restrict-255 is given a value between 0 and 255, restrict-255 should return that value. Since we expect that you'll want us to worry about negative numbers, we'd like restrict-255 to return 1 when given -1 as a parameter, 2 when given -2, and so on and so forth.

As you think about developing restrict-255, you decide that it would be easier to start with a simpler version, such as restrict-5. The Gimpers have graciously provided you with a table that gives you some interesting values for restrict-5.

(restrict-5 -7)3
(restrict-5 -6)4
(restrict-5 -5)5
(restrict-5 -4)4
(restrict-5 -3)3
(restrict-5 -2)2
(restrict-5 -1)1
(restrict-5 0)0
(restrict-5 1)1
(restrict-5 2)2
(restrict-5 3)3
(restrict-5 4)4
(restrict-5 5)5
(restrict-5 6)4
(restrict-5 7)3
(restrict-5 8)2
(restrict-5 9)1
(restrict-5 10)0
(restrict-5 11)1

a. What value should restrict-255 return when given the value 512? [5 points]

b. Write restrict-5. You need not document this procedure. [5 points]

c. Write restrict-255. You need not document this procedure. [5 points]

d. Write the more general (restrict val max), which restricts val to a value between 0 and max, inclusive, using the same general technique described above. You need not document this procedure. [5 points]

Problem 2: Tallying Vectors

You should be familiar with the tally procedure, which takes a predicate and a list and counts the number of values in the list for which the predicate holds. If you've forgotten the details of this procedure, you can find them in

Violet and Vim Vector feel slightly that there is no such procedure for their favorite data structure, the vector. They've called upon you to remedy the situation.

a. Given your training in CS151, you know that it's best to decide what a procedure should do before trying to figure out how it should do it. Begin by documenting tally-vector, a variant of tally that takes a predicate and a vector as parameters and returns the number of values in the vector for which the predicate holds. [5 points]

b. As you might guess, one natural technique for implementing tally-vector is with recursion. Since you have now mastered recursion, I think it's a good first strategy. Implement tally-vector recursively. You may not use tally or convert the vector to a list. [5 points]

c. Of course, you might also reflect that since tally-vector is so similar to tally, you might be able to build tally-vector using tally. That inclination is also reasonable. Implement tally-vector using tally and vector->list. [5 points]

d. Which of the two implementations do you prefer? Why? [5 points]

Problem 3: Map, Reformulated

As you may recall, the most common form of map takes two parameters, a function and a list of values. It then builds a new list of values by applying the function to each value in the original list.

Our friends Sarah and Steven Schemer have decided that it would be useful to have a version of map that takes two parameters, a list of functions and a single value, and returns of list of values. Given (f0 f1 f2 ... fn) and val as parameters, their mapfun procedure should return ((f0 val) (f1 val) (f2 val) ... (fn val)).

For example,

> (mapfun (list (left-section * 2) (left-section + 2)) 3)
(6 5)

a. Document mapfun. [10 points]

b. Implement mapfun. [10 points]

Problem 4: Some Higher-Order Definitions

A new set of students have joined the class, Harold and Harriet Hacker. They learn procedures by writing expressions that involve those procedures and then try to figure out what they've ended up with. They know each expression they've written creates a procedure, but they're not quite sure what the procedures do. Since they're new to the class, they're enlisting your aid. Given your repetitious training, you should be prepared to write the six Ps for their procedures.

a. Here's their first definition.

(define alpha (left-section apply *))

Document alpha. [5 points]

b. Here's a set of related definitions.

(define square (lambda (x) (* x x)))
(define add2 (left-section + 2))
(define beta (left-section mapfun (list square add2)))

Document beta. [5 points]

c. Here's yet another definition.

(define delta (right-section apply (list 5)))

Document delta. [5 points]

d. Since they're used to seeing more than one lambda in the definition of a higher-order procedure, they conclude their experimentation with procedure that involves three lambdas.

(define epsilon
  (lambda (binproc)
    (lambda (val1)
      (lambda (val2)
        (binproc val1 val2)))))

Describe the value returned by epsilon. You need not write all six P's for this part of the problem. [5 points]

Problem 5: Filtering Files

Write a procedure, (filter-file pred? infile outfile), that copies all the values in infile for which pred? holds to outfile, which it also creates. You can assume that pred? is a unary predicate and that infile and outfile are strings that name files. [20 points]

You need not document this procedure. You should test it, but you need not show me your tests.

Extra Credit

What problem did I say would be on the exam and then neglect to put on the exam (except in this form)? [3 points]

Solve that problem. [2 points]

Identify problems of grammar or spelling in the exam. [1 point each given to the whole class; 5 points max]



Wednesday, 6 November 2002 [Samuel A. Rebelsky]

Thursday, 7 November 2002 [Samuel A. Rebelsky]

Friday, 8 November 2002 [Samuel A. Rebelsky]

Sunday, 10 November 2002 [Samuel A. Rebelsky]

Monday, 11 November 2002 [Samuel A. Rebelsky]


Disclaimer: I usually create these pages on the fly, which means that I rarely proofread them and they may contain bad grammar and incorrect details. It also means that I tend to update them regularly (see the history for more details). Feel free to contact me with any suggestions for changes.

This document was generated by Siteweaver on Tue Dec 3 22:38:27 2002.
The source to the document was last modified on Mon Nov 11 15:03:10 2002.
This document may be found at

You may wish to validate this document's HTML ; Valid CSS! ; Check with Bobby

Samuel A. Rebelsky,