Lab Module C -- Writing tree and linear recursive procedures

CISC 280 Program Development Techniques

Goals:
  1. Build experience writing tree recursive and linearly recursive procedures.
  2. Be able to translate back and forth between C++ functions using loop constructs and recursively expressed Scheme procedures.

Reading: SICP (Structure and Interpretation of Computer Programs), finish Section 1.2

Homework exercises (Due at start of lab 26 Feb 01):

  1. SICP Exercise 1.12 (Pascal's triangle).

  2. The following C++ procedure computes the alternating sum of the squares of the positive integers up to n. Thus alternating_sum_squares(4) returns -10. Translate alternating_sum_squares into Scheme.
    int alternating_sum_squares(int n) // assume n > 0.
    { int a = 1;
      int sign = -1;
      for(int i = 2; i <= n; ++i)
      { a += sign*i*i;
        sign = -sign;
      }
      return a;
    }
    
    Remark: As an alternative to directly translating this method, you may if you wish work out an alternate method for (alternating-sum-squares n).

  3. Many interesting number theory problems concern numbers with a geometric property. Most basically, the number n = k*k is a "square" because n dots could be arranged in a k by k square. The number n = k(k+1)/2 is a triangular number for a similar reason. We won't explore triangular numbers here, but rather will consider numbers which can be written as a sum of squares (you can think of stacking the squares of dots like a child playing with blocks of various sizes). Some famous open questions in number theory concern how each positive integer may be written as a sum of squares.

    It can be challenging to find the fewest squares necessary to make a given number. As a start in that direction, the following C++ procedure determines if a positive integer can be written as the sum of two squares. It assumes the procedure isqrt(n) returns the integer square root, i.e., the greatest integer r such that r*r <= n < (r+1)*(r+1). Translate it into Scheme. You may use your integer square root procedure from the module B topping off exercise.

    int isqrt(int n); // defined elsewhere
    
    bool sum2squaresp(int n)
    { int a = 1; 
      int b = isqrt(n);
      while (a <= b)
      { while (a*a + b*b < n) a = a + 1;
        if (a*a + b*b == n) 
          return true;
        else 
        { // try a lower top.
          b = b - 1; 
          a = a - 1;
        }
      }
      // all possibilities failed, so...
      return false;
    }
    
    Remark: Some C/C++ programmers use a p at the end of a function name to indicate that it is a predicate (a bool valued function). But name your Scheme predicate sum2squares? . The question mark available in Scheme names is an even better convention.

    Flourishes (these are optional problems):

  4. SICP Exercise 1.11 (both parts).
  5. Define a predicate (sum-of-k-squares? n k) which returns true just in case the n can be written as the sum of exactly k squares. You may assume n and k are both positive. Hint: this problem has something in common with the count-change example in the text. You might start like this:
    (define (sum-of-k-squares? n k) (limited-sum-of-k-squares? n k (isqrt n)) )
    
    where you define
    (limited-sum-of-k-squares? n k b) 
    
    to return true if n is the sum of the squares of k numbers, each of which is no larger than b. Thus (limited-sum-of-k-squares 6 3 2) is true, but (limited-sum-of-k-squares 6 3 1) is false,