my attempt to do the exercises in sicp.

Thursday, January 6, 2011

sicp exercise 3.82



;; Exercise 3.82.  Redo exercise 3.5 on Monte Carlo integration in terms of streams. The stream version of estimate-integral will not have an argument telling how many trials to perform. Instead, it will produce a stream of estimates based on successively more trials.


;; get-random-stream is a procedure which generates a stream of random pairs of (x,y) which lie within x1 y1 x2 y2

(define (estimate-integral integral x1 x2 y1 y2)
  (define input (get-random-stream x1 x2 y1 y2))
  (define area (abs (* (- x1 x2) (- y1 y2))))
  (define (iter passed total in-stream)
    (let ((x (car (stream-car in-stream)))
          (y (cdr (stream-car in-stream))))
      (if (integral x y)
          (cons-stream (* area (/ (+ passed 1) (+ 1 total)))
                       (iter (+ 1 passed) (+ 1 total) (stream-cdr in-stream)))
          (cons-stream (* area (/ passed (+ 1 total)))
                       (iter passed (+ 1 total) (stream-cdr in-stream))))))
  (iter 0 0 input))

sicp exercise 3.81



;; Exercise 3.81.  Exercise 3.6 discussed generalizing the random-number generator to allow one to reset the random-number sequence so as to produce repeatable sequences of ``random'' numbers. Produce a stream formulation of this same generator that operates on an input stream of requests to generate a new random number or to reset the sequence to a specified value and that produces the desired stream of random numbers. Don't use assignment in your solution.


(define (display-line str)
  (display str)
  (newline))

(define (display-stream str num)
  (define (internal index)
    (if (> index num) 'printed
        (begin
          (display-line (stream-ref str index))
          (internal (+ 1 index)))))
  (newline)
  (internal 0))

(define (random-numbers input-stream rand-init)
  (define (rand-update n)(+ 10 n))
    (let ((command (stream-car input-stream)))
      (cond ((eq? command 'generate)
             (let ((random-number (rand-update rand-init)))
               (cons-stream random-number
                            (random-numbers (stream-cdr input-stream) random-number))))
            ((and (pair? command) (eq? (car command) 'reset))
              (let ((random-number (rand-update (cadr command))))
                (cons-stream random-number
                             (random-numbers (stream-cdr input-stream) random-number))))
            (else
              '()))))
              


(define infinite-input
  (cons-stream 'generate infinite-input))

(display-stream (random-numbers infinite-input 0) 20)

(define input
  (cons-stream 'generate
    (cons-stream 'generate
      (cons-stream 'generate
        (cons-stream (list 'reset 2)
          (cons-stream 'generate
            (cons-stream 'generate
              (cons-stream 'generate '()))))))))

(newline)
(display (stream-ref (random-numbers input 0) 0))(newline)
(display (stream-ref (random-numbers input 0) 1))(newline)
(display (stream-ref (random-numbers input 0) 2))(newline)
(display (stream-ref (random-numbers input 0) 3))(newline)
(display (stream-ref (random-numbers input 0) 4))(newline)
(display (stream-ref (random-numbers input 0) 5))(newline)
(display (stream-ref (random-numbers input 0) 6))(newline)

;Loading "sicp_prob_03.81.scm"...
;10
;20
;30
;40
;50
;60
;70
;80
;90
;100
;110
;120
;130
;140
;150
;160
;170
;180
;190
;200
;210
;
;10
;20
;30
;12
;22
;32
;42
;... done


Tuesday, January 4, 2011

sicp exercise 3.80



;; Exercise 3.80.  A series RLC circuit consists of a resistor, a capacitor, and an inductor connected in series, as shown in figure 3.36. If R, L, and C are the resistance, inductance, and capacitance, then the relations between voltage (v) and current (i) for the three components are described by the equations



;;and the circuit connections dictate the relations



;;Combining these equations shows that the state of the circuit (summarized by vC, the voltage across the capacitor, and iL, the current in the inductor) is described by the pair of differential equations



;;The signal-flow diagram representing this system of differential equations is shown in figure 3.37.



;;Figure 3.36:  A series RLC circuit.



;;Figure 3.37:  A signal-flow diagram for the solution to a series RLC circuit.

;;Write a procedure RLC that takes as arguments the parameters R, L, and C of the circuit and the time increment dt. In a manner similar to that of the RC procedure of exercise 3.73, RLC should produce a procedure that takes the initial values of the state variables, vC0 and iL0, and produces a pair (using cons) of the streams of states vC and iL. Using RLC, generate the pair of streams that models the behavior of a series RLC circuit with R = 1 ohm, C = 0.2 farad, L = 1 henry, dt = 0.1 second, and initial values iL0 = 0 amps and vC0 = 10 volts.


(define (display-line str)
  (display str)
  (newline))

(define (display-stream str num)
  (define (internal index)
    (if (> index num) 'printed
        (begin
          (display-line (stream-ref str index))
          (internal (+ 1 index)))))
  (newline)
  (internal 0))

(define (display-stream-pair p num)
  (define (internal index)
    (if (> index num) 'printed
        (begin
          (display-line (list (stream-ref (car p) index) (stream-ref (cdr p) index)))
          (internal (+ 1 index)))))
  (newline)
  (internal 0))
 


(define (scale-stream stream factor)
  (stream-map (lambda (x) (* x factor)) stream))

(define (add-streams s1 s2)
  (stream-map + s1 s2))

(define (integral delayed-integrand initial-value dt)
  (define int
    (cons-stream initial-value
                 (let ((integrand (force delayed-integrand)))
                   (add-streams (scale-stream integrand dt)
                                int))))
  int)

(define (RLC R L C dt)
  (lambda(vc0 il0)
    (define vc (integral (delay dvc) vc0 dt))
    (define il (integral (delay dil) il0 dt))
    (define dvc (scale-stream il (/ -1 C)))
    (define dil (add-streams (scale-stream il (/ (* -1 R) L))
                             (scale-stream vc (/ 1 L))))
    (cons vc il)))

(define RLC123 (RLC 1 0.2 1 0.1))

(display-stream-pair (RLC123 10 0) 40)


;; Output
;Loading "sicp_prob_03.80.scm"...
;(10 0)
;(10 5.)
;(9.5 7.5)
;(8.75 8.5)
;(7.9 8.625)
;(7.0375000000000005 8.2625)
;(6.211250000000001 7.6499999999999995)
;(5.446250000000001 6.930624999999999)
;(4.753187500000001 6.1884375)
;(4.134343750000001 5.470812500000001)
;(3.587262500000001 4.802578125000001)
;(3.107004687500001 4.194920312500001)
;(2.687512656250001 3.6509625000000008)
;(2.322416406250001 3.1692375781250006)
;(2.005492648437501 2.7458269921875007)
;(1.7309099492187507 2.375659820312501)
;(1.4933439671875006 2.0532848847656258)
;(1.2880154787109381 1.7733144259765632)
;(1.1106840361132817 1.5306649523437508)
;(.9576175408789066 1.3206744942285162)
;(.825550091456055 1.1391460175537114)
;(.7116354897006838 .9823480545048832)
;(.6134006842501954 .8469917721027835)
;(.528701507039917 .7301962281764895)
;(.4556818842222681 .6294488676082033)
;(.39273699746144775 .5425653759152357)
;(.33848045986992414 .4676511866883417)
;(.29171534120109 .40306582327913293)
;(.2514087588731767 .34739058224011143)
;(.21666970064916558 .29939967055664407)
;(.18672973359350117 .2580346856029048)
;(.1609262650332107 .222382209598203)
;(.1386880440733904 .19165423731570685)
;(.11952262034181971 .16517114069454863)
;(.10300550627236485 .14234688051818417)
;(.08877081822054643 .1226761933952745)
;(.07650319888101897 .10572350580791047)
;(.06593084830022793 .09111335234446472)
;(.05681951306578145 .07852210032234633)
;(.04896730303354682 .06767080669406389)
;(4.2200222364140436e-2 5.8319054863805356e-2)
;... done


sicp exercise 3.79


;; Exercise 3.79.  Generalize the solve-2nd procedure of exercise 3.78 so that it can be used to solve general second-order differential equations d2 y/dt2 = f(dy/dt, y).

(define (integral delayed-integrand initial-value dt)
  (define int
    (cons-stream initial-value
                 (let ((integrand (force delayed-integrand)))
                   (add-streams (scale-stream integrand dt)
                                int))))
  int)

(define (solve f y0 dy0 dt)
  (define y (integral (delay dy) y0 dt))
  (define dy (integral (delay ddy) dy0 dt))
  (define ddy (stream-map f y dy))
  y)

sicp exercise 3.78


;; Exercise 3.78. 



;;Figure 3.35:  Signal-flow diagram for the solution to a second-order linear differential equation.
;;Consider the problem of designing a signal-processing system to study the homogeneous second-order linear differential equation



;;The output stream, modeling y, is generated by a network that contains a loop. This is because the value of d2y/dt2 depends upon the values of y and dy/dt and both of these are determined by integrating d2y/dt2. The diagram we would like to encode is shown in figure 3.35. Write a procedure solve-2nd that takes as arguments the constants a, b, and dt and the initial values y0 and dy0 for y and dy/dt and generates the stream of successive values of y.


(define (display-line str)
  (display str)
  (newline))

(define (display-stream str num)
  (define (internal index)
    (if (> index num) 'printed
        (begin
          (display-line (stream-ref str index))
          (internal (+ 1 index)))))
  (newline)
  (internal 0))

(define (scale-stream stream factor)
  (stream-map (lambda (x) (* x factor)) stream))

(define (add-streams s1 s2)
  (stream-map + s1 s2))

(define (integral delayed-integrand initial-value dt)
  (define int
    (cons-stream initial-value
                 (let ((integrand (force delayed-integrand)))
                   (add-streams (scale-stream integrand dt)
                                int))))
  int)

(define (solve-2nd a b dt y0 dy0)
  (define y (integral (delay dy) y0 dt))
  (define dy (integral (delay ddy) dy0 dt))
  (define ddy (add-streams (scale-stream dy a)
                           (scale-stream y b)))
  y)


sicp exercise 3.77



;; Exercise 3.77.  The integral procedure used above was analogous to the ``implicit'' definition of the infinite stream of integers in section 3.5.2. Alternatively, we can give a definition of integral that is more like integers-starting-from (also in section 3.5.2):

;(define (integral integrand initial-value dt)
;  (cons-stream initial-value
;               (if (stream-null? integrand)
;                   the-empty-stream
;                   (integral (stream-cdr integrand)
;                             (+ (* dt (stream-car integrand))
;                                initial-value)
;                             dt))))

;When used in systems with loops, this procedure has the same problem as does our original version of integral. Modify the procedure so that it expects the integrand as a delayed argument and hence can be used in the solve procedure shown above.


(define (add-streams s1 s2)
  (stream-map + s1 s2))

(define (scale-stream stream factor)
  (stream-map (lambda (x) (* x factor)) stream))

(define (integral delayed-integrand initial-value dt)
  (cons-stream initial-value
               (let ((integrand (force delayed-integrand)))
                 (if (stream-null? integrand)
                     the-empty-stream
                     (integral (delay (stream-cdr integrand))
                               (+ (* dt (stream-car integrand))
                                  initial-value)
                               dt)))))


(define (solve f y0 dt)
  (define y (integral (delay dy) y0 dt))
  (define dy (stream-map f y))
  y)

(newline)
(display (stream-ref (solve (lambda (y) y) 1 0.001) 1000))


Sunday, January 2, 2011

sicp exercise 3.76



;; Exercise 3.76.  Eva Lu Ator has a criticism of Louis's approach in exercise 3.75. The program he wrote is not modular, because it intermixes the operation of smoothing with the zero-crossing extraction. For example, the extractor should not have to be changed if Alyssa finds a better way to condition her input signal. Help Louis by writing a procedure smooth that takes a stream as input and produces a stream in which each element is the average of two successive input stream elements. Then use smooth as a component to implement the zero-crossing detector in a more modular style.


(define (display-line str)
  (display str)
  (newline))

(define (display-stream str num)
  (define (internal index)
    (if (> index num) 'printed
        (begin
          (display-line (stream-ref str index))
          (internal (+ 1 index)))))
  (newline)
  (internal 0))

(define (make-zero-crossings input-stream last-value)
  (let ((avpt (/ (+ (stream-car input-stream) last-value) 2)))
    (cons-stream (sign-change-detector avpt last-value)
                 (make-zero-crossings (stream-cdr input-stream)
                                      avpt))))

(define (avg x y)(/ (+ x y) 2))

(define (smooth s)
  (define (iter x y str)
    (cons-stream (avg x y)
                 (iter y (stream-car str) (stream-cdr str))))
  (iter (stream-car s)
        (stream-car (stream-cdr s))
        (stream-cdr (stream-cdr s))))

(define (integers-from-n n)
  (cons-stream n (integers-from-n (+ 1 n))))

(define integers (integers-from-n 0))

(define (make-zero-crossings input-stream last-value)
  (cons-stream
   (sign-change-detector (stream-car input-stream) last-value)
   (make-zero-crossings (stream-cdr input-stream)
                        (stream-car input-stream))))

(define zero-crossings (make-zero-crossings (smooth (cons-stream 0 sense-data)) 0))


sicp exercise 3.75



;; Exercise 3.75.  Unfortunately, Alyssa's zero-crossing detector in exercise 3.74 proves to be insufficient, because the noisy signal from the sensor leads to spurious zero crossings. Lem E. Tweakit, a hardware specialist, suggests that Alyssa smooth the signal to filter out the noise before extracting the zero crossings. Alyssa takes his advice and decides to extract the zero crossings from the signal constructed by averaging each value of the sense data with the previous value. She explains the problem to her assistant, Louis Reasoner, who attempts to implement the idea, altering Alyssa's program as follows:

;(define (make-zero-crossings input-stream last-value)
;  (let ((avpt (/ (+ (stream-car input-stream) last-value) 2)))
;    (cons-stream (sign-change-detector avpt last-value)
;                 (make-zero-crossings (stream-cdr input-stream)
;                                      avpt))))

;This does not correctly implement Alyssa's plan. Find the bug that Louis has installed and fix it without changing the structure of the program. (Hint: You will need to increase the number of arguments to make-zero-crossings.)


(define (make-zero-crossings input-stream last-value last-avg-value)
  (let ((avpt (/ (+ (stream-car input-stream) last-value) 2)))
    (cons-stream (sign-change-detector avpt last-avg-value)
                 (make-zero-crossings (stream-cdr input-stream)
                                      (stream-car input-stream) avpt))))

sicp exercise 3.74


;;Exercise 3.74.  Alyssa P. Hacker is designing a system to process signals coming from physical sensors. One important feature she wishes to produce is a signal that describes the zero crossings of the input signal. That is, the resulting signal should be + 1 whenever the input signal changes from negative to positive, - 1 whenever the input signal changes from positive to negative, and 0 otherwise. (Assume that the sign of a 0 input is positive.) For example, a typical input signal with its associated zero-crossing signal would be

; ...1  2  1.5  1  0.5  -0.1  -2  -3  -2  -0.5  0.2  3  4 ......
;    0  0    0  0    0     -1  0   0   0     0    1  0  0 ...

;In Alyssa's system, the signal from the sensor is represented as a stream sense-data and the stream zero-crossings is the corresponding stream of zero crossings. Alyssa first writes a procedure sign-change-detector that takes two values as arguments and compares the signs of the values to produce an appropriate 0, 1, or - 1. She then constructs her zero-crossing stream as follows:

;(define (make-zero-crossings input-stream last-value)
;  (cons-stream
;   (sign-change-detector (stream-car input-stream) last-value)
;   (make-zero-crossings (stream-cdr input-stream)
;                        (stream-car input-stream))))
;
;(define zero-crossings (make-zero-crossings sense-data 0))

;Alyssa's boss, Eva Lu Ator, walks by and suggests that this program is approximately equivalent to the following one, which uses the generalized version of stream-map from exercise 3.50:

;(define zero-crossings
;  (stream-map sign-change-detector sense-data <expression>))

;Complete the program by supplying the indicated <expression>.


(define zero-crossings
  (stream-map sign-change-detector sense-data (cons-stream 0 sense-data)))


sicp exercise 3.73



;; Exercise 3.73. 

;;         v = v0 + (1/C)0ti dt + R i     




;;Figure 3.33:  An RC circuit and the associated signal-flow diagram.

;;We can model electrical circuits using streams to represent the values of currents or voltages at a sequence of times. For instance, suppose we have an RC circuit consisting of a resistor of resistance R and a capacitor of capacitance C in series. The voltage response v of the circuit to an injected current i is determined by the formula in figure 3.33, whose structure is shown by the accompanying signal-flow diagram.

;;Write a procedure RC that models this circuit. RC should take as inputs the values of R, C, and dt and should return a procedure that takes as inputs a stream representing the current i and an initial value for the capacitor voltage v0 and produces as output the stream of voltages v. For example, you should be able to use RC to model an RC circuit with R = 5 ohms, C = 1 farad, and a 0.5-second time step by evaluating (define RC1 (RC 5 1 0.5)). This defines RC1 as a procedure that takes a stream representing the time sequence of currents and an initial capacitor voltage and produces the output stream of voltages.

(define (scale-stream stream factor)
  (stream-map (lambda (x) (* x factor)) stream))

(define (integral integrand initial-value dt)
  (define int
    (cons-stream initial-value
                 (add-streams (scale-stream integrand dt)
                              int)))
  int)

(define (RC R C dt)
  (lambda(i v0)
    (add-stream (scale-stream i R)
                (integral (scale-stream i (/ 1 C)) v0 dt))))

(define RC1 (RC 5 1 0.5))


sicp exercise 3.72



; Exercise 3.72.  In a similar way to exercise 3.71 generate a stream of all numbers that can be written as the sum of two squares in three different ways (showing how they can be so written).


(define (display-line str)
  (display str)
  (newline))

(define (display-stream str num)
  (define (internal index)
    (if (> index num) 'printed
        (begin
          (display-line (stream-ref str index))
          (internal (+ 1 index)))))
  (newline)
  (internal 0))

(define (integers-from-n n)
  (cons-stream n (integers-from-n (+ 1 n))))

(define integers (integers-from-n 1))

(define (merge-weighted s1 s2 weight)
  (cond ((stream-null? s1) s2)
        ((stream-null? s2) s1)
        (else
         (let ((s1car (stream-car s1))
               (s2car (stream-car s2)))
           (cond ((< (weight s1car) (weight s2car))
                  (cons-stream s1car (merge-weighted (stream-cdr s1) s2 weight)))
                 (else
                  (cons-stream s2car (merge-weighted s1 (stream-cdr s2) weight))))))))

(define (f1 s t)
  (cons-stream (list (stream-car s) (stream-car t))
               (f1 s (stream-cdr t))))
(define (f0 s t weight)
  (cons-stream (list (stream-car s) (stream-car t))
               (merge-weighted (f1 s (stream-cdr t))
                               (f0 (stream-cdr s) (stream-cdr t) weight)
                               weight)))
(define (weighted-pairs s t weight) (f0 s t weight))

(define (square x)(* x x))
(define square-weighted-pairs (weighted-pairs integers integers (lambda(s)(+ (square (car s)) (square (cadr s))))))
;(display-stream square-weighted-pairs 50)

(define (check-eq-weight s weight)
  (let ((a (stream-car s))
        (b (stream-car (stream-cdr s)))
        (c (stream-car (stream-cdr (stream-cdr s)))))
    (if (and (= (weight a) (weight b))
             (= (weight b) (weight c)))
        (cons-stream (list (weight a) a b c)
                     (check-eq-weight (stream-cdr s) weight))
        (check-eq-weight (stream-cdr s) weight))))

(define result (check-eq-weight square-weighted-pairs (lambda(s)
                                                        (+ (square (car s))
                                                           (square (cadr s))))))

(display-stream result 4)

;Loading "sicp_prob_03.72.scm"...
;(325 (10 15) (6 17) (1 18))
;(425 (13 16) (8 19) (5 20))
;(650 (17 19) (11 23) (5 25))
;(725 (14 23) (10 25) (7 26))
;(845 (19 22) (13 26) (2 29))
;... done


sicp exercise 3.71


;; Exercise 3.71.  Numbers that can be expressed as the sum of two cubes in more than one way are sometimes called Ramanujan numbers, in honor of the mathematician Srinivasa Ramanujan.70 Ordered streams of pairs provide an elegant solution to the problem of computing these numbers. To find a number that can be written as the sum of two cubes in two different ways, we need only generate the stream of pairs of integers (i,j) weighted according to the sum i3 + j3 (see exercise 3.70), then search the stream for two consecutive pairs with the same weight. Write a procedure to generate the Ramanujan numbers. The first such number is 1,729. What are the next five?


(define (display-line str)
  (display str)
  (newline))

(define (display-stream str num)
  (define (internal index)
    (if (> index num) 'printed
        (begin
          (display-line (stream-ref str index))
          (internal (+ 1 index)))))
  (newline)
  (internal 0))

(define (integers-from-n n)
  (cons-stream n (integers-from-n (+ 1 n))))

(define integers (integers-from-n 1))

(define (merge-weighted s1 s2 weight)
  (cond ((stream-null? s1) s2)
        ((stream-null? s2) s1)
        (else
         (let ((s1car (stream-car s1))
               (s2car (stream-car s2)))
           (cond ((< (weight s1car) (weight s2car))
                  (cons-stream s1car (merge-weighted (stream-cdr s1) s2 weight)))
                 (else
                  (cons-stream s2car (merge-weighted s1 (stream-cdr s2) weight))))))))

(define (f1 s t)
  (cons-stream (list (stream-car s) (stream-car t))
               (f1 s (stream-cdr t))))
(define (f0 s t weight)
  (cons-stream (list (stream-car s) (stream-car t))
               (merge-weighted (f1 s (stream-cdr t))
                               (f0 (stream-cdr s) (stream-cdr t) weight)
                               weight)))
(define (weighted-pairs s t weight) (f0 s t weight))

(define (cube x)(* x x x))
(define cube-weighted-pairs (weighted-pairs integers integers (lambda(s)(+ (cube (car s)) (cube (cadr s))))))
;(display-stream cube-weighted-pairs 20)

(define (check-eq-weight s weight)
  (let ((a (stream-car s))
        (b (stream-car (stream-cdr s))))
    (if (= (weight a) (weight b))
        (cons-stream (list (weight a) a b)
                     (check-eq-weight (stream-cdr s) weight))
        (check-eq-weight (stream-cdr s) weight))))

(define ramanujan-numbers (check-eq-weight cube-weighted-pairs (lambda(s)
                                                                 (+ (cube (car s))
                                                                    (cube (cadr s))))))

(display-stream ramanujan-numbers 4)

;Loading "sicp_prob_03.71.scm"...
;(1729 (9 10) (1 12))
;(4104 (9 15) (2 16))
;(13832 (18 20) (2 24))
;(20683 (19 24) (10 27))
;(32832 (18 30) (4 32))
;... done


sicp exercise 3.70


;Exercise 3.70.  It would be nice to be able to generate streams in which the pairs appear in some useful order, rather than in the order that results from an ad hoc interleaving process. We can use a technique similar to the merge procedure of exercise 3.56, if we define a way to say that one pair of integers is ``less than'' another. One way to do this is to define a ``weighting function'' W(i,j) and stipulate that (i1,j1) is less than (i2,j2) if W(i1,j1) < W(i2,j2). Write a procedure merge-weighted that is like merge, except that merge-weighted takes an additional argument weight, which is a procedure that computes the weight of a pair, and is used to determine the order in which elements should appear in the resulting merged stream.69 Using this, generalize pairs to a procedure weighted-pairs that takes two streams, together with a procedure that computes a weighting function, and generates the stream of pairs, ordered according to weight. Use your procedure to generate

; a. the stream of all pairs of positive integers (i,j) with i < j ordered according to the sum i + j

; b. the stream of all pairs of positive integers (i,j) with i < j, where neither i nor j is divisible by 2, 3, or 5, and the pairs are ordered according to the sum 2 i + 3 j + 5 i j.


(define (display-line str)
  (display str)
  (newline))

(define (display-stream str num)
  (define (internal index)
    (if (> index num) 'printed
        (begin
          (display-line (stream-ref str index))
          (internal (+ 1 index)))))
  (newline)
  (internal 0))

(define (integers-from-n n)
  (cons-stream n (integers-from-n (+ 1 n))))

(define integers (integers-from-n 1))

(define (merge-weighted s1 s2 weight)
  (cond ((stream-null? s1) s2)
        ((stream-null? s2) s1)
        (else
         (let ((s1car (stream-car s1))
               (s2car (stream-car s2)))
           (cond ((< (weight s1car) (weight s2car))
                  (cons-stream s1car (merge-weighted (stream-cdr s1) s2 weight)))
                 (else
                  (cons-stream s2car (merge-weighted s1 (stream-cdr s2) weight))))))))

(define (f1 s t)
  (cons-stream (list (stream-car s) (stream-car t))
               (f1 s (stream-cdr t))))
(define (f0 s t weight)
  (cons-stream (list (stream-car s) (stream-car t))
               (merge-weighted (f1 s (stream-cdr t))
                               (f0 (stream-cdr s) (stream-cdr t) weight)
                               weight)))
(define (weighted-pairs s t weight) (f0 s t weight))

(display-stream (weighted-pairs integers integers (lambda(s)(+ (car s) (cadr s)))) 20)

(define (div-by x y)(= 0 (remainder x y)))
(define integers-not-div-by-2-3-5
  (stream-filter (lambda(x)
                   (not (or (div-by x 2)
                            (div-by x 3)
                            (div-by x 5))))
                 integers))

;(display-stream integers-not-div-by-2-3-5 20)

(define result (weighted-pairs integers-not-div-by-2-3-5
                               integers-not-div-by-2-3-5
                               (lambda(s)
                                 (let ((i (car s))
                                       (j (cadr s)))
                                   (+ (* 2 i)
                                      (* 3 j)
                                      (* 5 i j))))))

(display-stream result 20)

;Loading "sicp_prob_03.70.scm"...
;(1 1)
;(1 2)
;(2 2)
;(1 3)
;(2 3)
;(1 4)
;(3 3)
;(2 4)
;(1 5)
;(3 4)
;(2 5)
;(1 6)
;(4 4)
;(3 5)
;(2 6)
;(1 7)
;(4 5)
;(3 6)
;(2 7)
;(1 8)
;(5 5)

;(1 1)
;(1 7)
;(1 11)
;(1 13)
;(1 17)
;(1 19)
;(1 23)
;(1 29)
;(1 31)
;(7 7)
;(1 37)
;(1 41)
;(1 43)
;(1 47)
;(1 49)
;(1 53)
;(7 11)
;(1 59)
;(1 61)
;(7 13)
;(1 67)
;... done