drRacket: regarding lists - scheme

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)

Related

How to represent the following data structure in scheme r5rs

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.

Creating a list of lists in Racket

I am new to Racket programming, and I am working on a problem where I am given a list of numbers, and I have to make a list of list, of different combinations of numbers.
Something like :
(combine (list 3 1 2)) => (list
(list 31 32 33)
(list 21 22 3)
(list 11 12 13))
How do I achieve this in Racket?
Thank You
Just play with iterators and comprehension to implement a cartesian product that returns lists of lists, and a bit of arithmetic to obtain the right results. Try this:
(for/list ((i '(3 2 1)))
(for/list ((j '(1 2 3)))
(+ (* 10 i) j)))
Or alternatively, using more standard constructs (available in student languages):
(map (lambda (i)
(map (lambda (j)
(+ (* 10 i) j))
'(1 2 3)))
'(3 2 1))
Either way, it works as expected:
=> '((31 32 33) (21 22 23) (11 12 13))

fetch n-elements from a list Racket

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)

why does only the last expr in a lambda block get evaluated?

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

Partition help scheme

I have the following code, but when I run this example:
(partition 12 '(4 9 18 6 19 10 18 11 5 5 7 2 4 19 1 9 10 18 12))
I get
((4 9 6 10 11 5 5 7 2 4 1 9 10 12) (18 19 18 19 18))
in return.
I want it as following
((4 9 6 10 11 5 5 7 2 4 1 9 10 12) 18 19 18 19 18)
What should I do to change this? Thanks in favor
(require (lib "trace.ss"))
(define (partition pivot lon)
(if (null? lon)
'(()())
(let ((split-of-rest (partition pivot (cdr lon))))
(if (<= (car lon) pivot)
(list (cons (car lon) (car split-of-rest))
(cadr split-of-rest))
(list (car split-of-rest) (cons (car lon)
(car (cdr split-of-rest))))))))
This is how I solved it:
(define (partition pivot lon)
(define (partition pivot lon less more)
(if (null? lon)
(cons less more)
(if (<= (car lon) pivot)
(partition pivot (cdr lon) (append less (list (car lon))) more)
(partition pivot (cdr lon) less (append more (list (car lon)))))))
(partition pivot lon '() '()))
Dunno if this is a solution that you are looking for though.
In some Scheme interpreters (Racket, for instance) there's a built-in partition procedure. Alternatively, it's also included in SRFI 1. If available use it, it'll simplify your code:
(define (my-partition val lst)
(let-values (((low high) (partition (lambda (x) (<= x val)) lst)))
(cons low high)))
partition returns two values, the first one is a list of those elements that satisfy the predicate, and the second one a list of the elements that don't satisfy the predicate. It's easy to combine them using a cons to obtain the result in the format you want.
Alternatively, we could use call-with-values, as suggested by #leppie :
(define (my-partition val lst)
(call-with-values
(thunk (partition (lambda (x) (<= x val)) lst))
cons))
Either way, the result is as expected:
(my-partition 12 '(4 9 18 6 19 10 18 11 5 5 7 2 4 19 1 9 10 18 12))
=> '((4 9 6 10 11 5 5 7 2 4 1 9 10 12) 18 19 18 19 18)
I find the recursive approach difficult, here's a simpler, iterative way:
(define (partition pivot lst)
(let loop ((a '()) (b '()) (lst lst))
(cond
((null? lst) (cons (reverse a) (reverse b)))
((<= (car lst) pivot) (loop (cons (car lst) a) b (cdr lst)))
(else (loop a (cons (car lst) b) (cdr lst))))))
(partition 12 '(4 9 18 6 19 10 18 11 5 5 7 2 4 19 1 9 10 18 12))
=> '((4 9 6 10 11 5 5 7 2 4 1 9 10 12) 18 19 18 19 18)

Resources