<< Previous exercise (3.69) | Index | Next exercise (3.71) >>

(define (merge-weighted s1 s2 weight) (cond ((stream-null? s1) s2) ((stream-null? s2) s1) (else (let ((cars1 (stream-car s1)) (cars2 (stream-car s2))) (cond ((< (weight cars1) (weight cars2)) (cons-stream cars1 (merge-weighted (stream-cdr s1) s2 weight))) ((= (weight cars1) (weight cars2)) (cons-stream cars1 (merge-weighted (stream-cdr s1) s2 weight))) (else (cons-stream cars2 (merge-weighted s1 (stream-cdr s2) weight)))))))) (define (weighted-pairs s1 s2 weight) (cons-stream (list (stream-car s1) (stream-car s2)) (merge-weighted (stream-map (lambda (x) (list (stream-car s1) x)) (stream-cdr s2)) (weighted-pairs (stream-cdr s1) (stream-cdr s2) weight) weight))) (define weight1 (lambda (x) (+ (car x) (cadr x)))) (define pairs1 (weighted-pairs integers integers weight1)) (define weight2 (lambda (x) (+ (* 2 (car x)) (* 3 (cadr x)) (* 5 (car x) (cadr x))))) (define (divide? x y) (= (remainder y x) 0)) (define stream235 (stream-filter (lambda (x) (not (or (divide? 2 x) (divide? 3 x) (divide? 5 x)))) integers)) (define pairs2 (weighted-pairs stream235 stream235 weight2))

i think the WEIGHT function takes two arguments rather than one. So i don't understand meteorgan's solution

The weight procedure should accept one argument, which is a pair. Note that in this exercise, the merge-weighted procedure operates on a stream of pairs.

(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))) ((> (weight s1car) (weight s2car)) (cons-stream s2car (merge-weighted s1 (stream-cdr s2) weight))) (else (cons-stream s1car (cons-stream s2car (merge-weighted (stream-cdr s1) (stream-cdr s2) weight)))))))))

(define (merge-weighted stream1 stream2 weight) (cond ((stream-null? stream1) stream2) ((stream-null? stream2) stream1) (else (let ((stream1-car (stream-car stream1)) (stream2-car (stream-car stream2))) (if (> (weight stream1-car) (weight stream2-car)) (cons-stream stream2-car (merge-weighted stream1 (stream-cdr stream2) weight)) (cons-stream stream1-car (merge-weighted (stream-cdr stream1) stream2 weight))))))) (define (weighted-pairs s t weight) (cons-stream (list (stream-car s) (stream-car t)) (merge-weighted (stream-map (lambda (x) (list (stream-car s) x)) (stream-cdr t)) (weighted-pairs (stream-cdr s) (stream-cdr t) weight) weight))) ; a) (weighted-pairs integers integers (lambda (pair) (apply + pair))) ; b) (define 2-3-5-number (merge (merge (scale-stream integers 2) (scale-stream integers 3)) (scale-stream integers 5))) (weighted-pairs 2-3-5-number 2-3-5-number (lambda (pair) (let ((i (car pair)) (j (cadr pair))) (+ (* 2 i) (* 3 j) (* 5 i j)))))

>>> Thomas @Sphinxsky answer for b is incorrect. there i and j are only divisible by by 2,3 or 5, but they should both not be divisible by either of these numbers. Meteorgans solution is correct (didn't bother to check the rest)

>>> dekraai Isn't all answers incorrect, considering that the first pair is never compared?

For merge-weighted, it is important to include *both* stream heads if there is ever a tie in weight; we don't simply discard duplicates the way we did for merge.

`(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))) (let ((w1 (weight s1car)) (w2 (weight s2car))) (cond ((< w1 w2) (cons-stream s1car (merge-weighted (stream-cdr s1) s2 weight))) ((> w1 w2) (cons-stream s2car (merge-weighted s1 (stream-cdr s2) weight))) (else (cons-stream s1car (cons-stream s2car ;; must include both in case of ties! (merge-weighted (stream-cdr s1) (stream-cdr s2) weight))))))))))`

For weighted-pairs, order *within* the pair doesn't matter, so we need to stream-map *twice*, similarly to how we implemented all-pairs in a previous exercise. (I assume we are supposed to keep it general like this rather than assume that i <= j, since the condition "i <= j" is given in the examples part and part b).