Reputation: 588
Trying to produce an output of pairs that would look like (1 1) (1 2) (1 3) (2 2) (2 3) (3 3), if taking the first 6 elements of a stream. (The first 6 have 3 columns and it should print the pairs beginning with 1 and then 2 and then 3.) The code I have is:
(define (pairs s t)
(cons-stream (cons (stream-car s) (stream-car t))
(cons-stream
(stream-map (lambda (x) (cons (stream-car s) x))
(stream-cdr t))
(pairs (stream-cdr t) (stream-cdr s)))))
And if I run
(take 6 (pairs integers integers))
where take and integers are defined as follows:
(define (take n s)
(if (= n 0)
'()
(cons (stream-car s) (take (- n 1) (stream-cdr s)))))
(define integers (cons-stream 1 (add-streams ones integers)))
The result I get is:
((1 . 1)
((1 . 2) . #<promise>)
(2 . 2)
((2 . 3) . #<promise>)
(3 . 3)
((3 . 4) . #<promise>))
Upvotes: 1
Views: 287
Reputation: 71065
In Scheme,
(define (interleaved-pairs xs ys . args)
(let ((x (stream-car xs))
(ac (if (null? args) () (car args))))
(stream-append
(stream-map stream-car (list->stream (reverse ac)))
(stream-cons (list x (stream-car ys))
(interleaved-pairs
(stream-cdr xs)
(stream-cdr ys)
(cons
(stream-map (lambda(y)(list x y)) (stream-cdr ys))
(map stream-cdr ac)))))))
This should produce results in the order you wanted: (1 1) (1 2) (2 2) (1 3) (2 3) (3 3) (1 4) ...
.
You tagged this as racket also. As far as I can see in the Racket documentation, it has stream-first
in place of stream-car
, etc. For some reason it doesn't seem to have list->stream
, which can be defined quite straightforwardly with the apply
and stream
functions.
Here it is in a shorter notation.
ipairs xs ys = g xs ys [] where
g (x:xs) (y:ys) ac = map head (reverse ac) ++ (x,y) :
g xs ys (map ((,) x) ys : map tail ac)
Upvotes: 1