3.70 Exercise 3.70
merge-weighted can be defined as follows (note that, unlike merge, this does not deduplicate results):
(define (merge-weighted weight s t) (cond ((stream-null? s) t) ((stream-null? t) s) (else (let* ((a (stream-car s)) (b (stream-car t)) (wa (weight a)) (wb (weight b))) (if (< wa wb) (cons-stream a (merge-weighted weight (stream-cdr s) t)) (cons-stream b (merge-weighted weight s (stream-cdr t))))))))
We can then weight pairs from two streams like this:
(define (weighted-pairs weight s t) (if (or (stream-null? s) (stream-null? t)) the-empty-stream (cons-stream (list (stream-car s) (stream-car t)) (merge-weighted weight (stream-map (lambda (x) (list (stream-car s) x)) (stream-cdr t)) (weighted-pairs weight (stream-cdr s) (stream-cdr t))))))
For examples, the pairs of integers weighted by the sums of their elements:
> (display-stream (take-stream (weighted-pairs (lambda (p) (+ (car p) (cadr p))) integers integers) 20))
(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)
'done
And the pairs of integers that are not divisible by 2, 3, or 5 ordered by the sum 2i + 3j + 5ij
> (define filtered-integers (stream-filter (lambda (x) (not (or (divisible? x 2) (divisible? x 3) (divisible? x 5)))) integers))
> (define (weight p) (let ((i (car p)) (j (cadr p))) (+ (* 2 i) (* 3 j) (* 5 (+ i j)))))
> (display-stream (take-stream (weighted-pairs weight filtered-integers filtered-integers) 20))
(1 1)
(1 7)
(1 11)
(7 7)
(1 13)
(7 11)
(1 17)
(7 13)
(1 19)
(11 11)
(11 13)
(7 17)
(1 23)
(13 13)
(7 19)
(11 17)
(13 17)
(11 19)
(7 23)
(1 29)
'done