Note: this wiki is now retired and will no longer be updated!

The static final versions of the pages are left as a convenience for readers. Note that meta-pages such as "discussion," "history," etc., will not work.

SICP exercise 2.45

From Drewiki
Jump to: navigation, search
Comment The solution for this exercise requires the use of the PLT Scheme DrScheme graphical environment. Ensure the DrScheme language is set to Module before running the program.
Comment The picture language implemented by the PLT Scheme SICP picture package is slightly different than the picture language described in the text. The PLT package lacks the wave and rogers pictures; the solution provided here will use the diagonal-shading and einstein pictures provided by the PLT package instead. Also, painters in the PLT picture package don't know how to draw themselves. In order to draw a painter in the DrScheme graphical environment, use the paint procedure: it takes a single argument, the painter to draw, e.g.,

(paint einstein)

The (require ...) expression at the beginning of the program automatically loads the PLT picture package from the DrScheme web site. It may not work if you're attempting to run the program from behind a proxy or outbound firewall.

For more information on the PLT SICP picture package, see here.

Problem

right-split and up-split can be expressed as instances of a general splitting operation. Define a procedure split with the property that evaluating

(define right-split (split beside below))
(define up-split (split below beside))

produces procedures right-split and up-split with the same behaviors as the ones already defined.

Solution

The original definitions of these procedures are given as follows, from the text and from the solution to exercise 2.44:

(define (right-split painter n)
  (if (= n 0)
      painter
      (let ((smaller (right-split painter (- n 1))))
        (beside painter (below smaller smaller)))))
 
(define (up-split painter n)
  (if (= n 0)
      painter
      (let ((smaller (up-split painter (- n 1))))
        (below painter (beside smaller smaller)))))

The general split procedure returns a procedure which looks essentially the same as these two definitions, except that the two positioning operations are abstracted: the first operation operates on the identity painter, and on the result of applying the second operation to identical smaller painters. (Note that we can't easily use a lambda expression for the returned procedure because it's recursive.)

#lang scheme
(require (planet "sicp.ss" ("soegaard" "sicp.plt" 2 1)))
 
(define (split identity-op smaller-op)
  (define (rec-split painter n)
    (if (= n 0)
        painter
        (let ((smaller (rec-split painter (- n 1))))
          (identity-op painter (smaller-op smaller smaller)))))
  rec-split)
 
(define right-split (split beside below))
(define up-split (split below beside))

Test:

(paint (right-split einstein 2))

right-split-einstein

(paint (up-split einstein 2))

up-split-einstein

Personal tools