Google Answers Logo
View Question
Q: Help finding excerise soultions ( Answered 5 out of 5 stars,   1 Comment )
Subject: Help finding excerise soultions
Category: Computers > Programming
Asked by: mott85-ga
List Price: $10.00
Posted: 14 Oct 2004 19:00 PDT
Expires: 13 Nov 2004 18:00 PST
Question ID: 415080
I am trying to teach myself scheme so I have the book Structure and
interpretation of computer programs Second edition by Harold Abelson
and Gerald Jay Sussman. I have done some sample exercises however this
book provides no answers to check myself. Is there somewhere I can get
the answers to exercises: 
 Exercise 2.56 
 Exercise 2.74 
 Exercise 2.76 
 Exercise 2.77

Request for Question Clarification by googleexpert-ga on 16 Oct 2004 17:54 PDT
Hi mott85-ga,
Are you going through each exercise in the book?
If so, do you mind posting the solution to 2.40?

If not, can you post the solutions to 2.56,2.74,2.76 or 2.77?



Clarification of Question by mott85-ga on 17 Oct 2004 18:51 PDT
This one is long here is 2.40
I would apprecite it if i you can find proper soultions for the other ones.
(define (prime? x)
  (define (smallest-divisor n)
    (find-divisor n 2))
  (define (find-divisor n test-divisor)
    (cond ((> (square test-divisor) n) n)
          ((divides? test-divisor n) test-divisor)
          (else (find-divisor n (+ test-divisor 1)))))
  (define (divides? a b)
    (= (remainder b a) 0))
  (= x (smallest-divisor x)))

(define (square n) (* n n))

(define (prime-sum-pairs n)
  (define (unique-pairs n) ;; Added to simplify the prime-sum-pair procedure
    (define (make-a-pair i j n keep)
      (if (> i n)
          (if (< j i)
              (make-a-pair i (+ j 1) n (append keep (list (cons i j))))
              (make-a-pair (+ i 1) 1 n keep))))
    (cond ((= n 1) nil)
          ((= n 2)
           (list (cons 2 1)))
          (else (make-a-pair 3 1 n (list (cons 2 1))))))
   (define (make-pair-and-sum pair-list pair-and-sum-list)
       (if (null? pair-list)
           (if (prime? (+ (caar pair-list) (cdar pair-list)))
               (make-pair-and-sum(cdr pair-list)
                              (append pair-and-sum-list
                                        (list (caar pair-list)
                                              (cdar pair-list)
                                              (+ (caar pair-list)
                                                 (cdar pair-list))))))
               (make-pair-and-sum (cdr pair-list) pair-and-sum-list))))
  (cond ((< n 2) nil)
        ((= n 2) (list 2 1 3))
         (else (make-pair-and-sum (cdr (unique-pairs n)) (list (list 2 1 3))))))

(prime-sum-pairs 6)
Subject: Re: Help finding excerise soultions
Answered By: googleexpert-ga on 17 Oct 2004 20:50 PDT
Rated:5 out of 5 stars
Thank you very much for posting the solution to 2.40.

Here are the solutions to the exercises you requested:

2.56 [1]
(define (make-exponentiation b exp) 
  (cond ((=number? exp 0) 1) 
        ((=number? exp 1) b) 
           (list '** b exp))))

(define (base z) 
  (cadr z))

(define (exponent z) 
  (caddr z))

Define the test:

(define (exponentiation? x) 
  (and (pair? x) (eq? (car x) '**)))

Note: this test could be improved to make shure '** gets exactly two arguments.

In the deriv procedure add the following condition:

   ((exponentiation? exp) 
          (make-product (exponent exp) 
             (make-exponentiation (base exp) 
                (- (exponent exp) 1))) 
                (deriv (base exp) var))) 

2.74 [2]
(a)  Each division will have a private get-record operation, so each
division's package will look like this:

(define (install-research-division)
  (define (get-record employee file)
  (put 'get-record 'research get-record)

Then we can write a global get-record procedure like this:

(define (get-record employee division-file)
  ((get 'get-record (type-tag division-file))
   (contents division-file)))

It'll be invoked, for example, like this:
            (get-record '(Alan Perlis) research-personnel-list)

For this to work, each division's file must include a type tag
specifying which division it is.

If, for example, a particular division file is a sequence of
records, one per employee, and if the employee name is the CAR of 
each record, then that division can use ASSOC as its get-record
procedure, by saying

  (put 'get-record 'manufacturing assoc)

in its package-installation procedure.

(b)  The salary field might be in a different place in each
division's files, so we have to use the right selector based
on the division tag.

(define (get-salary record)
  (apply-generic 'salary record))

Each division's package must include a salary selector, comparable
to the magnitude selectors in the complex number example.

Why did I use GET directly in (a) but apply-generic in (b)?  In the
case of get-salary, the argument is a type-tagged datum.  But in the
case of get-record, there are two arguments, only one of which (the
division file) has a type tag.  The employee name, I'm assuming,
is not tagged.

(c)  Find an employee in any division

(define (find-employee-record employee divisions)
  (cond ((null? divisions) (error "No such employee"))
        ((get-record employee (car divisions)))
        (else (find-employee-record employee (cdr divisions)))))

This uses the feature that a cond clause with only one expression
returns the value of that expression if it's not false.

(d)  To add a new division, you must create a package for the division,
make sure the division's personnel file is tagged with the division name,
and add the division's file to the list of files used as argument to

2.76 [2]

To add a new operator:

First we must write a low-level procedure for that operator for each type,
like (magnitude-rectangular) and (magnitude-polar) if we're adding the
operator magnitude.  (If we're using a package system, we can add a
local definition of MAGNITUDE to each package.)  Then...

For conventional style, we write a generic operator procedure
(magnitude) that invokes the appropriate lower-level procedure
depending on the type of its operand.

For data-directed style, we use PUT to insert entries in the
procedure matrix for each low-level procedure; there is no new
high-level procedure required.

For message-passing style, we modify each of the type dispatch
procedures to accept a new message corresponding to the new
operator, dispatching to the appropriate low-level procedure.

To add a new type:

First we must write a low-level procedure for that type for each
operator, like (real-part-polar), (imag-part-polar),
(magnitude-polar), and (angle-polar) if we're inventing the
polar type.  (If we're using a package system, we can create
a new POLAR package with local definitions of REAL-PART, etc.)

For conventional style, we modify each of the generic operator
procedures (real-part), (imaginary-part), etc. to know about the
new type, dispatching to the appropriate lower-level procedures.

For data-directed style, we use PUT to insert entries, as for
a new operator.

For message-passing style, we write a new type dispatch procedure
that accepts messages 'real-part, 'imag-part, etc. and dispatches
to the appropriate lower-level procedure.

Which is most appropriate:

Conventional style is certainly INappropriate when many new types
will be invented, because lots of existing procedures need to be

Similarly, message-passing is INappropriate when many new operators
will be invented and applied to existing types.

Data-directed programming is a possible solution in either case, and is
probably the best choice if both new types and new operators are likely.
It's also a good choice if the number of types or operators is large in
the first place, whether or not new ones will be invented, because it
minimizes the total number of procedures needed (leaving out the generic
dispatch procedures for each type or operator) and thereby reduces the
chances for error.

As you'll see in chapter 3, message-passing style takes on new importance
when a data object needs to keep track of local state.  But you'll see
later in the chapter (mutable data) that there are other solutions to
the local state problem, too.

Message-passing is also sometimes sensible when there are lots of types,
each of which has its own separate set of operators with unique names, so
that a data-directed array would be mostly empty.

2.77 [3,2]
;: (put 'real-part '(complex) real-part)
;: (put 'imag-part '(complex) imag-part)
;: (put 'magnitude '(complex) magnitude)
;: (put 'angle '(complex) angle)

Starting with

          (magnitude '(complex rectangular 3 . 4))

we call MAGNITUDE giving

          (apply-generic  'magnitude  '(complex rectangular 3 . 4))

The apply-generic function (see pg. 184) just uses GET to find the
entry corresponding to 'magnitude and '(complex), and gets the same
function MAGNITUDE that we invoked in the first place.  This
time, however, the argument to MAGNITUDE is (CONTENTS OBJ)
so that the first type flag (COMPLEX) is removed.  In other
words, we end up calling

          (magnitude '(rectangular 3 . 4))
Calling the function MAGNITUDE again, this becomes :

          (apply-generic 'magnitude '(rectangular 3 . 4))
The apply-generic function now looks up the entry for 'magnitude and
'(rectangular) and finds the MAGNITUDE function from the RECTANGULAR
package; that function is called with '(3 . 4) as its argument, which
yields the final answer...  (sqrt (square 3) (square 4))  ==>  5


One more thing, I don't know if all the solutions are in this book but
you might want to check out:
The Solutions Manual to The Structure and Interpretation of Programs page:
Price: 25.00

[Search Strategy]
exercise number AND exercise text

Please let me know if you have anymore questions.
Thank you.


Clarification of Answer by googleexpert-ga on 22 Oct 2004 19:33 PDT
I appreciate your 5-Star rating of me.
Thank you!
mott85-ga rated this answer:5 out of 5 stars

Subject: Re: Help finding excerise soultions
From: paul_schleifer-ga on 15 Oct 2004 03:49 PDT
Can you post the questions?

Important Disclaimer: Answers and comments provided on Google Answers are general information, and are not intended to substitute for informed professional medical, psychiatric, psychological, tax, legal, investment, accounting, or other professional advice. Google does not endorse, and expressly disclaims liability for any product, manufacturer, distributor, service or service provider mentioned or any opinion expressed in answers or comments. Please read carefully the Google Answers Terms of Service.

If you feel that you have found inappropriate content, please let us know by emailing us at with the question ID listed above. Thank you.
Search Google Answers for
Google Answers  

Google Home - Answers FAQ - Terms of Service - Privacy Policy