<< 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)))))))))

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).