I have a vector list (3 6 8 2 ) and want to divide each element of the vector by 4 and return the vector
ex:- (div4 #(3 6 8 2))
'#(3/4 6/4 8/4 2/4)
You can use vector-map to apply a procedure to every element of a vector, as:
(define (div4 vec)
(vector-map (lambda (x) (/ x 4)) vec))
For example,
> (div4 #(4 8 12 16))
'#(1 2 3 4)
Related
Am a beginner to Scheme a dialect of Lisp, am trying to implement a function sum-vector that takes two vectors of numbers as arguments and returns a vector with the sum of the corresponding elements of the input vectors.
I have tried the following code but i can't figure out how to sum two vectors with different lengths.
Here is my current code
#lang scheme
(define sum-vector
(lambda (vec-1 vec-2)
(let* ((len (vector-length vec-1))
(result (make-vector len)))
(do ((index 0 (+ index 1)))
((= index len) result)
(vector-set! result index
(+ (vector-ref vec-1 index)
(vector-ref vec-2 index)))))))
(sum-vector (vector 4 6 8 3) (vector 5 6 7))
When i run the above code it works perfectly for vectors with same lengths e.g (sum-vector (vector 4 6 8) (vector 5 6 7)) returns #(9 12 15) I want it to work similarly for different lengths e.g (sum-vector (vector 4 6 8 3) (vector 5 6 7)) should return #(9 11 15 3) but i can't figure out the logic for doing that.
One possible solution is to append zeros to each vector to make their lengths equal and then use vector-map:
(define (zero-vector len)
(make-vector len 0))
(define (append-zeros vec max-len)
(vector-append vec (zero-vector (- max-len (vector-length vec)))))
(define (sum-vector v1 v2)
(let ((max-len (max (vector-length v1)
(vector-length v2))))
(vector-map +
(append-zeros v1 max-len)
(append-zeros v2 max-len))))
Tests:
> (sum-vector (vector 1 2 3) (vector 1 2 3 4 5 6))
'#(2 4 6 4 5 6)
> (sum-vector (vector) (vector 1 2 3 4 5 6 7 8))
'#(1 2 3 4 5 6 7 8)
Another, Racket-specific way.
Racket has something called comprehensions, which allow for easy iteration over containers. In particular, for/vector returns a vector of the results:
> (define v1 (vector 4 6 8 3))
> (define v2 (vector 5 6 7))
> (for/vector ([e1 v1] [e2 v2]) (+ e1 e2))
'#(9 12 15)
Note that the resulting vector is the length of the shortest container being iterated over. You can tell it to produce a vector of a given length, though:
> (for/vector #:length (vector-length v1) ([e1 v1] [e2 v2]) (+ e1 e2))
'#(9 12 15 0)
It fills in the extra elements with 0. Combine that with vector-copy!, which copies a range of elements from one vector to another at given offsets to copy the extra elements from the larger vector to the smaller (Or do nothing if they're the same length), and you get:
(define (sum-vector v1 v2)
(let ([sum-helper
(lambda (short long)
(let ([result (for/vector #:length (vector-length long)
([e1 short] [e2 long])
(+ e1 e2))])
(vector-copy! result (vector-length short)
long (vector-length short) (vector-length long))
result))])
(if (< (vector-length v1) (vector-length v2))
(sum-helper v1 v2)
(sum-helper v2 v1))))
Examples:
> (sum-vector (vector 4 6 8 3) (vector 5 6 7))
'#(9 12 15 3)
> (sum-vector (vector 1 2 3) (vector 1 2 3 4 5 6))
'#(2 4 6 4 5 6)
> (sum-vector (vector) (vector 1 2 3 4 5 6 7 8))
'#(1 2 3 4 5 6 7 8)
I need to write a function that produces the nth column of a matrix in Racket without using recursion. For example (list (list 1 2 3) (list 2 3 4) (list 6 7 9)) if I wanted the 2nd column I would receive (list 2 3 7).
I tried (append (map (lambda (n) (list-ref (list-ref M) n) n)) M)), but it keeps showing me an error.
The attempted solution uses list-ref twice, which is not needed, and one of those calls does not have enough arguments: (list-ref M) has the function taking only one argument, but it requires two arguments -- a list and an integer.
The list-ref function will return an indexed element from an input list, so (list-ref '(1 2 3) 1) will return 2. Consider what map will do here: the matrix is represented as a list of lists (a list of rows), i.e., as ((1 2 3) (2 3 4) (6 7 9)). The map function will act on the members of the input list, which are the lists (1 2 3), (2 3 4), and (6 7 9). By mapping the list-ref function over that input, you can take whichever element you want from the sublists. So, (map (lambda (row) (list-ref row 1)) '((1 2 3) (2 3 4) (6 7 9))) would evaluate to (2 3 7), as desired.
Here is a function that lets you take any column from a matrix:
(define (nth-column M n)
(map (lambda (row) (list-ref row n)) M))
Sample interactions:
scratch.rkt> (define M '((1 2 3)
(2 3 4)
(6 7 9)))
scratch.rkt> (nth-column M 1)
'(2 3 7)
scratch.rkt> (nth-column M 0)
'(1 2 6)
scratch.rkt> (nth-column M 2)
'(3 4 9)
How can I build a function that receives a list and builds 2 lists that on the first one are all the even numbers and on the other one are all the odd numbers?
For the input: (fun '(1 2 3 4 5 6))
the output will be: ((2 4 6) (1 3 5)).
There's a built-in for that, simply use partition and provide the right predicate. The rest of the code is just for capturing the returned values and building the output list:
(define (my-partition lst)
(let-values ([(evens odds) (partition even? lst)])
(list evens odds)))
For example:
(my-partition '(1 2 3 4 5 6))
=> '((2 4 6) (1 3 5))
The following code, I thought, should define a stream of random numbers between 1 and 10:
(define random-stream (stream-cons (random 1 11) random-stream))
However, what it actually does is define a stream of a specific random number. For example:
> (stream->list (stream-take random-stream 10))
'(5 5 5 5 5 5 5 5 5 5)
I presume this is the random number that (random 1 11) produces when the definition is first parsed. I got around this by making random-stream an argument-less function:
(define (random-stream) (stream-cons (random 1 11) (random-stream)))
This works:
> (stream->list (stream-take (random-stream) 10))
'(6 1 10 9 4 2 2 3 3 10)
So it looks to me that constants are, understandably, evaluated at read time, whereas functions are evaluated at call time. Usually this wouldn't matter, but in the case of a stream -- where you've got a recursive definition -- this makes a difference.
Is this how it works, or is it more subtle than this? Are there other cases one should be aware of regarding this difference?
Making random-stream an argument-less function is the correct solution.
(define (random-stream) (stream-cons (random 1 11) (random-stream)))
I will explain why.
When you define a stream normally with (define my-stream (stream-cons ....)), there is only one value for the stream. Any reference to my-stream will produce the same value.
(define my-stream (stream-cons (random 1 11) my-stream))
The my-stream inside the "rest" is literally the same value eq? to the one my-stream.
> (eq? my-stream (stream-rest my-stream))
#true
So because they are the same value, they can be substituted in function calls. If (stream-first my-stream) returns 5, then (stream-first (stream-rest my-stream)) must also return 5. (This is because stream-first is a "pure" function in the sense that it returns the same output for the same inputs.)
> (eq? (stream-first my-stream) (stream-first (stream-rest my-stream)))
#true
This is not the case with the function version because every time the function is called it creates a new stream value.
(define (random-stream) (stream-cons (random 1 11) (random-stream)))
> (eq? (random-stream) (random-stream))
#false
> (eq? (stream-first (random-stream)) (stream-first (random-stream)))
#false
Since the "rest" field also calls (random-stream), the rest is different from the whole.
> (define generated-stream (random-stream))
> (eq? generated-stream (stream-rest generated-stream))
#false
> (eq? (stream-first generated-stream) (stream-first (stream-rest generated-stream)))
#false
I agree with the other answer that the problem with OP code is that random-stream is a stream for which (stream-first random-stream) is some random number, while (stream-rest random-stream) is also the same stream beginning with the same number.
I don't quite agree with "an argument-less function is the correct solution," though.
One alternative solution would be to use stream-map to map random numbers over the natural numbers:
(define random-stream/1-10
(stream-map (lambda (x) (random 1 11)) (in-naturals)))
It would be even better to create a function that makes a stream of random numbers:
(define (random-stream a b)
(stream-map (lambda (x) (random a b)) (in-naturals)))
This function can be used to create a stream (note that in-naturals is also a function that creates streams):
random_streams.rkt> (define my-stream (random-stream 1 11))
random_streams.rkt> (stream->list (stream-take my-stream 10))
'(1 1 2 7 5 7 4 2 2 9)
Using this idea of a function that creates streams, the stream-cons method can be rescued:
(define (random-stream-cons a b)
(stream-cons (random a b) (random-stream-cons a b)))
When stream-first is called on a stream created with random-stream-cons, a random number is returned; when stream-rest is called on the same stream, another stream with a random number as its first element is returned.
The created streams are persistent:
random_streams.rkt> (stream->list (stream-take random-stream/1-10 10))
'(10 9 9 1 2 7 6 2 6 6)
random_streams.rkt> (stream->list (stream-take random-stream/1-10 15))
'(10 9 9 1 2 7 6 2 6 6 10 1 2 8 5)
random_streams.rkt> (define my-stream-1 (random-stream 1 11))
random_streams.rkt> (stream->list (stream-take my-stream-1 10))
'(1 4 1 10 7 9 9 9 2 9)
random_streams.rkt> (stream->list (stream-take my-stream-1 15))
'(1 4 1 10 7 9 9 9 2 9 2 3 9 9 10)
random_streams.rkt> (define my-stream-2 (random-stream-cons 1 11))
random_streams.rkt> (stream->list (stream-take my-stream-2 10))
'(10 4 6 1 4 2 10 5 3 6)
random_streams.rkt> (stream->list (stream-take my-stream-2 15))
'(10 4 6 1 4 2 10 5 3 6 1 5 7 5 5)
This random-stream-cons/1-10 function is essentially the same as the earlier random-stream-cons function (but with no arguments); yet neither of them are streams. Both of them are functions that create streams:
(define (random-stream-cons/1-10) (stream-cons (random 1 11) (random-stream-cons/1-10)))
Each time that one of these stream creation functions is called, a new stream is returned:
random_streams.rkt> (stream->list (stream-take (random-stream-cons/1-10) 10))
'(10 8 3 10 8 8 1 8 4 5)
random_streams.rkt> (stream->list (stream-take (random-stream-cons/1-10) 10))
'(1 8 7 3 8 2 2 10 6 5)
This might be just what is desired; such functions are very useful, for example, in iteration contexts:
random_streams.rkt> (for ([x (stream-take (random-stream 1 11) 5)])
(displayln x))
2
8
9
1
3
So, functions that return streams are useful, and the resulting streams can be bound to a symbol if desired. For streams that may be needed multiple times with different values, arguments can be provided in custom stream-creation functions. But for one-off streams, stream-map already does the job of returning a stream which can be bound to a symbol just as OP had originally written.
In Scheme, I am trying to iterate through a list adding each element from a portion of the list.
For example, if I had ((1 2 5) (1 2) (1 5) (1) (2 5) (2) (5) ()) for a list, I am trying to add the first part ( 1 2 5 ) and then the second part ( 1 2 ) and so on in order to see if each element adds up to a specific number.
Hope this makes sense, tried my best to explain this.
If someone could help me figure this problem out, I would really appreciate it.
To add the numbers of a (small) list you can use apply:
> (apply + '(1 2 3))
6
which is the same as
> (+ 1 2 3)
6
In order to apply this to a list of sublists, use map:
(define (f lst)
(map (lambda (sublst) (apply + sublst))
lst))
> (f '((1 2 5) (1 2) (1 5) (1) (2 5) (2) (5) ()))
'(8 3 6 1 7 2 5 0)
For larger list you might want to replace apply by foldl or equivalent.