How can I fetch n-elements from a list,
I know about first, rest etc, but what if I want the first 3 elements in a list,
I.E
(get-first 3 (list 1 2 3 4 5 6)) -> (list 1 2 3)
(get-first 5 (list 54 33 2 12 11 2 1 22 3 44)) -> (list 54 33 2 12 11)
This is not homework, but this code will help me complete the bigger picture of an assignment, I am really stuck and just need a few hints.
I am not allowed to use Lambda or build-list and no recursion, I somehow need to b able to do this with just map, filter, foldr etc...
As was mentioned by #AlexisKing, you can simply use the take procedure that's built-in in Racket:
(take '(1 2 3 4 5 6) 3)
=> '(1 2 3)
(take '(54 33 2 12 11 2 1 22 3 44) 5)
=> '(54 33 2 12 11)
If for some reason that's not allowed you can still roll your own version using higher-order procedures and no explicit recursion, but do notice that not using lambda is impossible, the allowed procedures you mention (map, filter, foldr) all receive a lambda as a parameter, and anyway all procedures in Scheme are lambdas under the hood.
Here's a contrived solution, passing an accumulator that remembers in what index we're in the input list while traversing it, and building the output list in the cdr part. It can't be done without using a lambda, but if it bothers you to see it there, extract it to a helper procedure and pass it along:
(define (get-first n lst)
(reverse
(cdr
(foldr (lambda (e acc)
(if (= (car acc) n)
acc
(cons (add1 (car acc))
(cons e (cdr acc)))))
'(0 . ())
(reverse lst)))))
It still works as expected, but never do such a complicated thing when a built-in procedure will do the same:
(get-first 3 '(1 2 3 4 5 6))
=> '(1 2 3)
(get-first 5 '(54 33 2 12 11 2 1 22 3 44))
=> '(54 33 2 12 11)
Related
In Python the data structure looks like this: [([1 2 3], [8 9 10])] (a list of tuple, where tuple is of size 2, and each tuple element is a list again)
How would I represent the same in Scheme r5rs?
This is what I tried: (list (cons `(1 2 3) `(8 9 10)))
But running (display (list (cons `(1 2 3) `(8 9 10)))) gives (((1 2 3) 8 9 10)) whereas I want (((1 2 3) (8 9 10)))
Edit
Using only lists (as per #Will Ness answer here):
(list ; a pair of elements,
(list 1 2 3) ; 1 each is itself
(list 8 9 10))) ; 2 a list
works.
And I can access the 2nd element of the tuple by
(cadr (car x)) which gives (8 9 10) (which is correct)
I was just thinking how would I build this up using cons since my tuple will only contain 2 elements and from what I know cons are used to represent a pair in Scheme. Any ideas on how to do this using cons?
[([1 2 3], [8 9 10])] (a list of tuple, where tuple is of size 2, and each tuple element is a list again)
(list ; a list of
(list ; a pair of elements,
(list 1 2 3) ; 1 each is itself
(list 8 9 10))) ; 2 a list
Scheme is untyped, so we can just use lists for tuples. It is simpler that way -- the access is uniform. The first is car, the second cadr.
Your way is correct as well. What really determines whether it is or not is how you can access your data to retrieve its constituents back. And with your way you can indeed, too: the first element will be car and the second -- cdr.
(update to the question edit:) whether you use (cons 1 (cons 2 '())) or (list 1 2) is immaterial. the resulting structure in memory is the same.
There is an infinity of ways to represent data. You have been presented a way. Here is other way:
(define mk/data
(lambda (a b)
(lambda (?)
(cond ((eq? ? 'repr) (list (list a b)))
((eq? ? 'first) a)
((eq? ? 'second) b)))))
(define data/test (mk/data '(1 2 3) '(8 9 10)))
(data/test 'repr)
(data/test 'first)
(data/test 'second)
This is another way how the big systems actually represent data.
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.
so i have 3 lists.
(define list1 '(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 15 16 17 18 19 20))
(define list2 '(2 5 6 8 10))
(define list3 '(1 4 8 9 13 15 18 19 20 25 27 29 ))
So begically, the list 1 is a list which contains 1 to 20.
What i want to do is, if i want to
list1 - list2 = '(1 3 4 6 7 9 11 12 13 14 15 16 17 18 19 20)
or,
list1 - list3 = (2 3 5 6 10 11 12 14 16 17)
I tried with length of the list but did not work but i want to keep all the list1 values except duplicated values with list3.
also, i want to do
list1 - list2 then, store the result from list1-list2 on list1, then do another subtraction like,
list1 - list2
store the result of # 1 in list1.
list1 - list3
can anyone give me some solution for this? Thank you so much!
Are you working with Set Theory? If so, (remove*) solves the problem but it's not the procedure that describes set difference.
Set difference is A\B is defined by:
A\B={x,such that x is in A and x is not in B}
Therefore you need a procedure that tells you wheter an element is in a list or not. Then your difference code would look like:
(define difference
(λ (A B)
(remove* (list #f) (map
(λ (x)
(if (not (in x B))
x
#f
)) A))))
In the above example I use remove*, and in my opinion it's not very elegant, so why not trying recursion? It's Racket in the end :).
(define difference2
(λ (A B res)
(cond
((empty? A) (reverse res))
((not (in (car A) B)) (difference2 (cdr A) B (cons (car A) res)))
(else (difference2 (cdr A) B res))
)))
Note how in difference2 i made no use of maps or removes.
The reverse function is used just in case you want the result to be ordered.
Analyze both examples, try to understand what I'm doing and post your results.
Let us know of any doubt!
EDIT:
Oh and about the other problem of assigning values of an operation to another variable (C++ like), you can do it very much like in C++. :p
Example
(define C (sum A B))
or
(define foo (+ (* pi x) (* 6 sigma)))
Can we get rid of your step 2, "store the result of #1 in list 1"? That sort of mutation just gives me the hives.
I think you're just trying to remove the elements from both lists 2 and 3 from list 1. You might do it like this:
(remove* (append list2 list3) list1)
yields....
'(3 7 11 12 14 16 17)
I wrote this following simple piece of scheme just to see whether Scheme is doing dynamic or static binding.
Now I was expecting line 17 (myFunc 5 6) to evaluate to 56 (because I know Scheme has static-scoping).
But when I execute the code, all I get is 6 (without the 5) which makes no sense!
Could anyone please tell me what makes it print only 6?
2(define myFunc
3 (lambda (a b)
4 (define aref
5 (lambda ()
6 a))
7 (define bref
8 (lambda ()
9 b))
10 (define innerFunc
11 (lambda (a b)
12 (aref)
13 (bref)))
14
15 (innerFunc 1 2)))
16
17(myFunc 5 6)
The body of a lambda is implicitly inside a begin form. And a begin returns the value of the last expression. So this:
((lambda () 1 2 3))
Will evaluate to the same value as this:
(begin 1 2 3)
... Which is the number 3. Now if you need to simultaneously return two or more values try this (works in Racket):
(values 1 2 3)
=> 1
2
3