I want to generate a stream of twin primes such that the stream would be as follows
((3 5) (5 7) (11 13) (17 19) ...)
and so on. I have a function that generates a stream of prime numbers, and a function that pairs them together. Where I'm confused is how to alter my pairing function so that only twin primes are paired together. My pairing function is:
(define (pairs s t)
(cons-stream
(list (stream-car s) (stream-car t))
(interleave
(stream-map (lambda (x) (list (stream-car s) x))
(stream-cdr t))
(pairs (stream-cdr s) (stream-cdr t)))))
Currently I receive the following output when passing in identical prime streams
((2 2) (2 3) (3 3) (2 5) (3 5) ...)
Add a (stream-filter (lambda (x) (= (- (cadr x) (car x)) 2)) ...) at the obvious spot.
You should only pair-up the adjacent primes:
(define (stream-zip s t)
(cons-stream
(list (stream-car s) (stream-car t))
(stream-zip (stream-cdr s) (stream-cdr t))))
Then you keep only the pairs of twins out of all adjacent pairs:
(define (twin primes)
(stream-filter ...
(stream-zip primes (stream-cdr primes))))
Related
I'm trying to understand how this function works.
(define (sieve stream)
(cons-stream
(stream-car stream)
(sieve (stream-filter
(lambda (x)
(not (divisible? x (stream-car stream))))
(stream-cdr stream)))))
(define primes (sieve (integers-starting-from 2)))
Simply, I use a stream that generates all the integers starting from 2 and, according to the book, it filters the rest of the stream that is not divisible by current element for each new element. How can this
filter all the integers that are not divisible by current element without actually reading all the integers?
The definitions
(define (sieve stream)
(cons-stream (stream-car stream)
(sieve
(stream-filter (lambda (x) (not (divisible? x (stream-car stream))))
(stream-cdr stream)))))
(define primes (sieve (integers-starting-from 2)))
mean that
primes
=
(sieve
(integers-starting-from 2))
=
(cons-stream 2
(sieve
(stream-filter (lambda (x) (not (divisible? x 2)))
(integers-starting-from 3))))
=
(cons-stream 2
(cons-stream 3
(sieve
(stream-filter (lambda (x) (not (divisible? x 3)))
(stream-filter (lambda (x) (not (divisible? x 2)))
(integers-starting-from 4))))))
=
(cons-stream 2
(cons-stream 3
(sieve
(stream-filter (lambda (x) (not (divisible? x 3)))
(stream-filter (lambda (x) (not (divisible? x 2)))
(integers-starting-from 5))))))
=
(cons-stream 2
(cons-stream 3
(cons-stream 5
(sieve
(stream-filter (lambda (x) (not (divisible? x 5)))
(stream-filter (lambda (x) (not (divisible? x 3)))
(stream-filter (lambda (x) (not (divisible? x 2)))
(integers-starting-from 6))))))))
and further
=
....
=
(cons-stream 2
(cons-stream 3
(cons-stream 5
(cons-stream 7
(sieve
(stream-filter (lambda (x) (not (divisible? x 7)))
(stream-filter (lambda (x) (not (divisible? x 5)))
(stream-filter (lambda (x) (not (divisible? x 3)))
(stream-filter (lambda (x) (not (divisible? x 2)))
(integers-starting-from 9))))))))))
=
....
=
(cons-stream 2
(cons-stream 3
(cons-stream 5
(cons-stream 7
(cons-stream 11
(sieve
(stream-filter (lambda (x) (not (divisible? x 11)))
(stream-filter (lambda (x) (not (divisible? x 7)))
(stream-filter (lambda (x) (not (divisible? x 5)))
(stream-filter (lambda (x) (not (divisible? x 3)))
(stream-filter (lambda (x) (not (divisible? x 2)))
(integers-starting-from 12))))))))))))
=
....
which, hopefully, should give you a clearer picture of what is going on here.
(NB: a follow up entry).
The trick is to think how stream-filter works. It is a function from streams to other streams, and this means that it does not actually need to filter the elements of the stream yet: instead it can return a stream which, as you ask for its elements, will filter them suitably.
In particular here is an implementation of stream-filter which I have called filter-stream:
(define (filter-stream test? stream)
(cond
((stream-empty? stream)
stream)
((test? (stream-car stream))
(cons-stream (stream-car stream)
(filter-stream test? (stream-cdr stream))))
(else
(filter-stream predicate? (stream-cdr stream)))))
You can see how this works: it chunters down the stream it is given until it finds an element which passes the filter (or until it runs out of stream), at which point it uses cons-stream to construct a new stream consisting of the element that passed the predicate and the result of filtering all the other elements with the same predicate. But constructing that stream doesn't involve calling the predicate on all its elements: it just requires you to make a promise that, at the point someone asks you for an element of that stream, you will indeed filter the elements suitably to return the appropriate element.
In other words stream-filter is a function which takes a stream, which is a potentially infinite object and returns another stream, which again is potentially infinite. And it does this by simply promising to you that, at the point when you ask for some prefix of that infinite stream, it will then compute it for you, safe in the knowledge that you can never ask for all the elements of the stream.
sieve itself then repeatedly stacks these streams on top of each other: each time it finds a prime it constructs a stream which filters out multiples of that prime, from the stream it has been given which is already filtering out all multiples of primes lower than the prime it has just found.
This is a problem related to ex3.51 in SICP, here is the code
(define (cons-stream x y)
(cons x (delay y)))
(define (stream-car stream) (car stream))
(define (stream-cdr stream) (force (cdr stream)))
(define (stream-map proc s)
(if (stream-null? s)
the-empty-stream
(cons-stream
(proc (stream-car s))
(stream-map proc (stream-cdr s)))))
(define (stream-enumerate-interval low high)
(if (> low high)
the-empty-stream
(cons-stream
low
(stream-enumerate-interval (+ low 1) high))))
(define (stream-ref s n)
(if (= n 0)
(stream-car s)
(stream-ref (stream-cdr s) (- n 1))))
(define (show x)
(display x)
x)
;test
(stream-map show (stream-enumerate-interval 0 10))
the output is 012345678910(0 . #<promise>).
but I thought the delay expression in cons-stream delayed the evaluation, if i use a different processing function in stream-map like lambda (x) (+ x 1) the output (1 . #<promise>) is more reasonable, so why does display print all the numbers?
The problem is with this definition:
(define (cons-stream x y)
(cons x (delay y)))
It defines cons-stream as a function, since it uses define.
Scheme's evaluation is eager: the arguments are evaluated before the function body is entered. Thus y is already fully calculated when it is passed to delay.
Instead, cons-stream should be defined as a macro, like
(define-syntax cons-stream
(syntax-rules ()
((_ a b) (cons a (delay b)))))
or we can call delay explicitly, manually, like e.g.
(define (stream-map proc s)
(if (stream-null? s)
the-empty-stream
(cons
(proc (stream-car s))
(delay
(stream-map proc (stream-cdr s))))))
Then there'd be no calls to cons-stream in our code, only the (cons A (delay B)) calls. And delay is a macro (or special form, whatever), it does not evaluate its arguments before working but rather goes straight to manipulating the argument expressions instead.
And we could even drop the calls to delay, and replace (cons A (delay B)) with (cons A (lambda () B)). This would entail also reimplementing force (which is built-in, and goes together with the built-in delay) as simply (define (force x) (x)) or just calling the (x) manually where appropriate to force a stream's tail.
You can see such lambda-based streams code towards the end of this answer, or an ideone entry (for this RosettaCode entry) without any macros using the explicit lambdas instead. This approach can change the performance of the code though, as delay is memoizing but lambda-based streams are not. The difference will be seen if we ever try to access a stream's element more than once.
See also this answer for yet another take on streams implementation, surgically modifying list's last cons cell as a memoizing force.
Streams of order and data are given and I need to order the data according to the order-stream.
#lang racket
(define the-empty-stream '())
(define (stream-car stream)
(car stream))
(define-syntax cons-stream
(syntax-rules ()
((cons-stream x y)
(cons x (delay y)))))
(define (stream-cdr stream)
(force (cdr stream)))
(define stream-null? null?)
(define (integers-starting-from n)
(stream-cons n (integers-starting-from (+ n 1))))
(define integers (integers-starting-from 1))
(define order-stream (stream-cons 2 1))
(define data-stream (stream-cons 5 6))
(define (reorder order-stream data-stream)
(cond ((stream-null? order-stream) the-empty-stream)
((stream-null? data-stream) the-empty-stream)
(else (stream-cons (stream-ref data-stream
(stream-car order-stream))
(reorder (stream-cdr order-stream) data-stream)))))
When I execute (reorder order-stream data-stream) I get #stream as output instead of 6 . #promise. This is my programming assignment so instead of giving complete code please give some hints instead.
Racket has a built-in stream-cons, which you're accidentally calling, instead of cons-stream as you intended to use.
Look at what you have:
(define (reorder order-stream data-stream)
^^^^^^^^^^^^
(cond ((stream-null? order-stream) the-empty-stream)
((stream-null? data-stream) the-empty-stream)
(else (stream-cons (stream-ref data-stream
(stream-car order-stream))
(reorder (stream-cdr order-stream) data-stream)))))
^^^^^^^^^^^^^^^^^^^^^^^^^
(define (stream-cdr stream)
(force (cdr stream)))
what kind of thing (stream-cdr stream) is expected to return?
and then you're calling
(define order-stream (cons-stream 2 1))
What is order-stream's cdr?
Stream programming is fun. For instance, to calculate partial sums of a stream, p-s [a,b,c...] = a, a+b, a+b+c, ..., we can write
(define (partial-sums xs init)
(cons-stream init
(partial-sums (stream-cdr xs)
(+ (stream-car xs) init))))
We can easily abstract away the + as a general binary operation argument:
(define (scanl + xs init)
(cons-stream init
(scanl + (stream-cdr xs)
(+ (stream-car xs) init))))
and call it as, e.g.
(define factorials (scanl * integers 1))
Another, interesting way to define scanl, is
(define (scanlist + xs init)
(define rs (cons-stream init
(combine-streams + xs rs)))
rs)
Writing combine-streams (a.k.a. zipWith in Haskell) is a straightforward deal.
In Racket, be sure to work in full language, where define is recursive, analogous to letrec (not let), or else the last one won't work (can you see why?).
I was wondering if anyone had any advice on writing the mandelbrot stream. I have wrote the following functions for myself to help:
(define (make-complex a b) (cons a b))
(define (real-coeff c) (car c))
(define (imag-coeff c) (cdr c))
(define (c-add c d)
(make-complex (+ (real-coeff c) (real-coeff d))
(+ (imag-coeff c) (imag-coeff d))))
(define (c-mult c d)
(make-complex (- (* (real-coeff c) (real-coeff d))
(* (imag-coeff c) (imag-coeff d)))
(+ (* (real-coeff c) (imag-coeff d))
(* (imag-coeff c) (real-coeff d)))))
(define (c-length c)
(define (square x) (* x x))
(sqrt (+ (square (real-coeff c))
(square (imag-coeff c)))))
I have that fz(x) = x2 +z. The stream should return: a, fz(a), fz(fz(a)), fz(fz(fz(a))). I am confused on how to use the functions that I wrote to create a stream that has this output. Anyone have some good advice as to where to go with this?
Start with a value for z and make your function fz(x) like:
(define (make-fz z) (lambda (x) (+ z (* 2 x))))
Now, using srfi-41 stream library, define a stream just as you've indicated:
Try it out (with z of 0):
> (stream->list (stream-take 10 (stream-iterate (make-fz 0) 1)))
(1 2 4 8 16 32 64 128 256 512)
Note: that stream-iterate is defined something like:
(define-stream (stream-iterate fz a)
(stream-cons a (stream-iterate fz (fz a))))
As uselpa said, Scheme has built-in complex numbers. The functions you mentioned are provided as follows:
make-rectangular
real-part
imag-part
+
*
magnitude
As for the second part of your question, what is z? It's hard to answer this without knowing what you're wanting.
Is there an analog of Python's itertools.count in Racket? I want to create an infinite stream of evenly spaced numbers. in-naturals is similar to what i want, but does not provide step. I'd want not to reinvent the wheel, but if there's no equivalent function, how to write one? (i presume, generators should be used)
You can get the same functionality of Python's count using in-range with an infinite end value:
(define (count start step)
(in-range start +inf.0 step))
For example:
(define s (count 2.5 0.5))
(stream-ref s 0)
=> 2.5
(stream-ref s 1)
=> 3.0
(stream-ref s 2)
=> 3.5
(stream-ref s 3)
=> 4.0
Making the function yourself can be done in a single line:
(define (stream-from n s) (stream-cons n (stream-from (+ n s) s)))
To test it, you here is an example that prints 100000 numbers:
#lang racket
(require racket/stream)
(define (stream-from n s) (stream-cons n (stream-from (+ n s) s)))
(define (stream-while s p)
(let ([fst (stream-first s)])
(if (p fst) (stream-cons fst (stream-while (stream-rest s) p)) empty-stream)))
(define test (stream-while (stream-from 0 1) (λ (x) (< x 100000))))
(stream-for-each println test)