SOLUTIONS FOR EXERCISE SET #4

1. Define a Scheme predicate that tests whether a given list is palindromic -- whether its first element is equal? to its last, its second to its next-to-last, and so on.

(define palindromic?
  (lambda (li)
    (equal? li (reverse li))))
or

(define palindromic?
  (lambda (li)
    (palin-helper li (reverse li) (quotient (length li) 2))))

(define palin-helper
  (lambda (li rev steps-remaining)
    (or (zero? steps-remaining)
        (and (equal? (car li) (car rev))
             (palin-helper (cdr li) (cdr rev) (sub1 steps-remaining))))))

(define sub1
  (lambda (n)
    (- n 1)))
2. Define a Scheme procedure display-structure that uses display to print out a representation of any symbolic structure, as defined in exercise set #3. It should use the following representation conventions:

a. The null object should be displayed as #n.

b. A symbol should be displayed as itself; for instance, the symbol alpha should be displayed as alpha.

c. A pair should be displayed as a left parenthesis, the displayed version of its left field, a space, a dot, another space, the displayed version of its right field, and a right parenthesis. Use recursive calls to display-structure to print the left and right fields.

I don't care what value display-structure returns. #<unspecified> would be fine.

(define display-structure
  (lambda (struct)
    (cond ((null? struct) (display "#n"))
          ((symbol? struct) (display struct))
          ((pair? struct) (display "(")
                          (display-structure (car struct))
                          (display " . ")
                          (display-structure (cdr struct))
                          (display ")"))
          (else (error "display-structure: requires a symbolic structure")))))
3. Define a Scheme procedure that returns the number of pair-records that make up a given symbolic structure. (In other words, in the box-and-arrows diagram for the structure, how many of those domino-shaped boxes would there be?)

(define pair-count
  (lambda (struct)
    (if (pair? struct)
        (+ 1 (pair-count (car struct)) (pair-count (cdr struct)))
        0)))
4. Define a Scheme procedure that constructs and returns the mirror image of a given symbolic structure -- the symbolic structure that contains the same constituents, but with all cars and cdrs swapped.

(define mirror-image
  (lambda (struct)
    (if (pair? struct)
        (cons (mirror-image (cdr struct)) (mirror-image (car struct)))
        struct)))
5. Repeat exercise 4 of exercise set #3, but this time define a procedure that obtains the result by an iterative process.

(define range-sum-it
  (lambda (start stop)
    (range-sum-it-helper start stop 0)))

(define range-sum-it-helper
  (lambda (start stop acc)
    (if (< stop start)
        acc
        (range-sum-it-helper (add1 start) stop (+ start acc)))))

(define add1
  (lambda (n)
    (+ n 1)))
6. Repeat exercise 1 of exercise set #3, using let-expressions to simplify the code.

(define quadratic-roots
  (lambda (a b c)
    (cond ((not (zero? a))
           (let ((discriminant (- (* b b) (* 4 a c)))
                 (denominator (* 2 a)))
             (if (zero? discriminant)
                 (list (/ (- b) denominator))
                 (list (/ (+ (- b) (sqrt discriminant)) denominator)
                       (/ (- (- b) (sqrt discriminant)) denominator)))))
          ((not (zero? b))
           (list (/ (- c) b)))
          ((not (zero? c))
           '())
          (else (display "All numbers are roots.")
                (newline)))))
7. Repeat exercise 10 of exercise set #3, using a letrec-expression to define the helper procedure locally.

(define iota
  (lambda (n)
    (letrec ((helper
              (lambda (n so-far)
                (if (zero? n)
                    so-far
                    (helper (sub1 n) (cons (sub1 n) so-far))))))
      (helper n '()))))
8. Define a Scheme procedure display-in-binary that writes out, as a side effect, the binary numeral for a given natural number. For instance, the call (display-in-binary 42) should cause the numeral 101010 to be written out. I don't care what value display-in-binary returns.

(define display-in-binary
  (lambda (n)
    (if (< n 2)
        (display n)
        (begin
          (display-in-binary (quotient n 2))
          (display (remainder n 2))))))
9. Define a Scheme procedure filter that takes two arguments, a predicate and a list, and returns a list that contains just the elements of the given list that satisfy the given predicate (that is, the elements for which applying the predicate to the element would return #t). For instance, (filter odd? '(3 8 6 1 4 9 2)) should return (3 1 9).

(define filter
  (lambda (pred ls)
    (cond ((null? ls) '())
          ((pred (car ls)) (cons (car ls) (filter pred (cdr ls))))
          (else (filter pred (cdr ls))))))
10. The Catalan sequence is defined by the following recursion:

  • C(0) is 1.

  • For any positive integer n, C(n) is (C(0) * C(n - 1)) + (C(1) * C(n - 2)) + ... + (C(k) * C(n - k - 1)) + ... + (C(n - 2) * C(1)) + (C(n - 1) * C(0)).
  • In other words, to obtain C(n), find all the ways of multiplying together two earlier members of the Catalan sequence whose subscripts add up to n - 1 and add up all the products.

    Here are some values of the sequence:

    C(0) = 1
    C(1) = 1
    C(2) = 2
    C(3) = 5
    C(4) = 14
    C(5) = 42
    
    Define a Scheme procedure that takes n as an argument and computes C(n).

    (define Catalan
      (lambda (n)
        (letrec ((helper
                  (lambda (index-1 index-2 acc)
                    (if (negative? index-2)
                        acc
                        (helper (add1 index-1)
                                (sub1 index-2)
                                (+ acc
                                   (* (Catalan index-1)
                                      (Catalan index-2))))))))
          (if (zero? n)
              1
              (helper 0 (sub1 n) 0)))))
    
    This procedure shown above is very inefficient; there are faster ways to compute the same values. (Exercise for the mathematically ambitious student: Prove that C(n) equals the binomial coefficient (2n)-choose-(n - 1).)


    created June 13, 1996
    last revised June 13, 1996

    John David Stone (stone@math.grin.edu)