CS 450 Homework 4
Paul Robertson
Spring, 2005


Due Monday, March 28, 4:30 PM

These exercises concern streams and delayed evaluation, and provide some practice using them in a non-trivial example.

One of the most well-known quotations in mathematical circles is Hardy's account of a visit he paid to Ramanujan. The quote is contained in footnote 70 on page 342 of the text, but I can't resist repeating it here:


I remember once going to see him when he was lying ill at Putney. I had ridden in taxi-cab No. 1729, and remarked that the number seemed to me a rather dull one, and that I hoped it was not an unfavorable omen. `No,' he replied, `it is a very interesting number; it is the smallest number expressible as the sum of two cubes in two different ways.'

The book calls numbers having this property Ramanujan numbers. (Actually, I have never seen this term used anywhere else, but the quote is so famous that any mathematician would know what is meant by it.) These exercises conclude with a remarkable method for calculating these numbers.

Put your answers to these problems in the file ram.scm in your ass4 directory. This file should begin with some definitions from the textbook, which are included here or for DrScheme users here. You should copy these definitions into the top of your file ram.scm (in addition to any other definitions you might find useful before starting the code for the various problems below). This is important: ram.scm should not load any other files -- it should be a self-contained file that includes any code it needs.

Also, if you find it convenient, you can create a separate text file notes.txt to hold more extended discussions of the problems and the code you wrote. (Of course, the code should still be commented in place.) You don't need to do this. But I will collect a file notes.txt if you have one.

  1. Define a function
    (display-n stream n)
    that prints the first n elements of stream, each on a separate line.

  2. As explained in section 3.5.2, we can define an infinite stream of ones and use this to define the stream of positive integers:
    (define ones (cons-stream 1 ones))

    (define integers (cons-stream 1 (add-streams ones integers)))
    Type in these definitions and verify that they work by using the display-n procedure. Generate the stream notdiv-235 of all integers that are not divisible by any of the numbers 2, 3, or 5. (Use stream-filter.)

  3. The following procedure takes two infinite streams and interleaves them, selecting elements alternately from each stream:
    (define (interleave s t)
    (cons-stream (stream-car s)
    (interleave t (stream-cdr s))))
    This is like the procedure on page 341 of the text, but without the check for an empty stream, since we are assuming that both s and t are infinite streams.

    Test the procedure by interleaving the stream of integers that are not divisible by 7 with the stream of integers not divisible by 3. Call this resulting stream nd73. What are the first few elements of the resulting stream? What expression did you evaluate to find this result?

  4. The stream nd73 that you constructed in the last problem contains repeated elements, and also elements that are "out of order". We can fix these problems by replacing the interleave procedure with a more sophisticated one called merge which takes two ordered streams of integers (i.e., the elements of each stream are arranged in increasing order) and produces an ordered stream as a result, omitting duplicates of elements that appear in both streams. The merge procedure is defined as follows (this is actually taken from page 331 in the text):
    (define (merge s1 s2)
    (cond ((stream-null? s1) s2)
    ((stream-null? s2) s1)
    (else
    (let ((s1car (stream-car s1))
    (s2car (stream-car s2)))
    (cond ((< s1car s2car)
    (cons-stream s1car (merge (stream-cdr s1) s2)))
    ((> s1car s2car)
    (cons-stream s2car (merge s1 (stream-cdr s2))))
    (else
    (cons-stream s1car
    (merge (stream-cdr s1)
    (stream-cdr s2)))))))))
    Use this procedure to merge the stream of integers that are not divisible by 7 with the stream of integers that are not divisible by 3. Call the stream you get in this manner nd73a. (This problem can of course be done more simply. But I want you to do it this way in preparation for later problems.)

    1. What is the 21st element of nd73? (Be careful. We are "counting from 1". That is, the initial element of the stream is element number 1, not element number 0.)

    2. What is the 21st element of nd73a?

  5. Exercise 3.56 on page 331. Use display-n to print the first few elements of the stream S. Also answer the following two questions:

    1. What are the 6 numbers immediately following 405 in the sequence?

    2. If you can, give a proof (or at least, a convincing argument) that the four bulleted facts in the Exercise in the book are all true.

  6. Exercise 3.66 on page 341. Before doing this exercise, be sure to read the section "Infinite streams of pairs" on pages 338--341.

  7. Exercise 3.70 on page 342.

    Give the name part-a to the stream which you produce for part a.

    Give the name part-b to the stream which you produce for part b.

    In doing this problem, note the following:

  8. Exercise 3.71 on page 342.

    You should finish by constructing the stream ram, each of whose elements is a list. The first element of the stream ram is the list

                     (1729 (1 12) (9 10))

    because 1729 = 13 + 123 = 93 + 103, and the other elements of the stream ram are built from the other Ramanujan numbers similarly.

    You will undoubtedly find it useful to create one or more auxiliary functions in doing this problem. Please explain carefully in comments what you are doing.

  9. Exercise 3.54 (page 331). (This is only for extra credit. The other problems are much more important. You might find this amusing, though.)