weirdness in clojure map function - list

the first strange thing about map in clojure is in following snippet:
(apply map list '((1 a) (2 b) (3 c)))
The result is surprising for me:
((1 2 3) (a b c))
Anyone could explain how it works?

(apply f x '(y z)) is equivalent to (f x y z), so your code is equivalent to (map list '(1 a) '(2 b) '(3 c)).
When called with multiple lists, map iterates the lists in parallel and calls the given function with one element from each list for each element (i.e. the first element of the result list is the result of calling the function with the first element of each list as its arguments, the second is the result for the second elements etc.).
So (map list '(1 a) '(2 b) '(3 c)) first calls list with the first elements of the lists (i.e. the numbers) as arguments and then with the second elements (the letters). So you get ((list 1 2 3) (list 'a 'b 'c)).

Related

How to fix contract violation errors in scheme DrRacket?

(define is1?
(lambda (tuple)
(if (and (= 2 (length tuple))
(= 1 (- (cadr tuple) (car tuple)))
(list? tuple))
#t
#f)))
(define greenlist?
(lambda (x) (andmap is1? x)))
(greenlist? '((2 4 6) (5 6) (1 2)))
(greenlist? '(3 4 5 6))
The second command: (greenlist? '(3 4 5 6)) returns an error when it should return false.
Instead I get this error:
length: contract violation
expected: list?
given: 3
What should I change in my code so it returns false instead of an error?
Here is the definition of a greenlist:
A greenlist is a non-empty list of pairs of integers where a pair of
integers is a list of exactly two integers and where each pair '( x y) has the property that y – x = 1.
Example: '((5 6) (3 4) (2 3) (-5 -4)) is a greenlist.
The problem is that the order of the conditions matters: in an and expression the conditions are evaluated in left-to-right order, if one condition is false then the other conditions are skipped (short-circuit evaluation).
Your input is a list of lists, so you should test first if the current element is an actual list - otherwise you'll attempt to take the length of an object which isn't a list (the number 3 in your example), which is an error.
By the way: it's possible to simplify the code, you don't actually need to use an if, just return the value of the condition:
(define is1?
(lambda (tuple)
(and (list? tuple) ; you must ask this first!
(= 2 (length tuple))
(= 1 (- (cadr tuple) (car tuple))))))

Scheme - Cartesian product with 'map'?

I am trying to write a function that returns the cartesian product of 2 sets (lists) with the help of the 'map' function and I want each pair of elements in the returned list to be a vector.
(cartesian-product '(1 2 3) '(a b))
'(#(3 a) #(3 b) #(2 a) #(2 b) #(1 a) #(1 b))
My initial idea was to make a separate procedure that makes a vector out element c (constant) in set 2 and element n in set 1 where element n changes for each iteration and then proceed to map this separate function with set 2. So for example, if I use the above lists (in the code sample) I would get 3 different vectors from this separate function:
#'(a 1) #'(a 2) #'(a 3)
And when using map on this I would get the result:
'(#'(a 1) #'(a 2) #'(a 3) #'(b 1) #'(b 2) #'(b 3))
But I realized that I would instead get a result that looks something like this:
'((#'(a 1) #'(a 2) #'(a 3)) (#'(b 1) #'(b 2) #'(b 3)))
because the separate function has to be recursive and it would have to return a list when finished.
Now I am back to square one and I am out of ideas. Help please...
Should mention that this is a school assignment and I am not allowed to use any predefined functions except for simple ones like:
cdr,car,cons,map etc
Try to keep it as basic as possible. I have only been using Scheme for like a month so go easy on me :)
We can nest two maps and flatten the result at the end, making sure to create a vector in the right place:
(define (cartesian-product lst1 lst2)
(apply append
(map (lambda (x)
(map (lambda (y)
(vector x y))
lst2))
lst1)))
It works as expected:
(cartesian-product '(1 2 3) '(a b))
=> '(#(1 a) #(1 b) #(2 a) #(2 b) #(3 a) #(3 b))

Creating a list of lists of repeating elements

this is a homework problem I'm stuck on. I have to create a function in Racket without using explicit recursion or local, that takes in a list of pairs, where the first element of each pair is a non-negative integer, and produces a new list of lists, where each list is k occurrences of the second element in each pair, where k is the first element of each pair. For example (expand-pairs (list (list 1 2) (list 3 4))) would produce (list (list 2) (list 4 4 4))
I got some code working, but only if the second element is a number. Since the question doesn't specify what type of element the second element is, I assume it needs to work for any element. So my function can solve the above example, but can't solve (expand-pairs (list (list 1 'a) (list 3 'b))).
Here is my code:
(define (expand-pairs plst)
(map
(lambda (x)
(map
(lambda (y) (+ (first (rest x)) y))
(build-list (first x) (lambda (z) (- z z)))))
plst))
My main problem is I don't know how to create a list of length k without using recursion or build-list, but then if I use build-list it creates a list of numbers, and I don't know how to convert that to a list of symbols or any other element.
Can anyone point me in the right direction?
Here's another possible implementation, building on #RomanPekar's answer but a bit more idiomatic for Racket:
(define (expand-pairs lst)
(map (lambda (s)
(build-list (first s) (const (second s))))
lst))
It makes use of the higher-order procedures map, const and build-list to create an implementation without using explicit recursion or local. The trick here is to understand how the following expression will return 5 copies of x:
(build-list 5 (const 'x))
^ ^ ^
#copies constant element
=> '(x x x x x)
Something like this:
(define (expand-pairs plst)
(map (lambda(x) (build-list (car x) (lambda(k) (cadr x)))) plst))
You don't have to use k in the build-list, just take second element of pair.

functions and lists in scheme/racket

How would you define a function which takes one argument, which should be a list, and returns the elements in the
list which are themselves lists?
(check-expect (find-sublists ’(1 2 () (3) (a b c) a b c))
’(() (3) (a b c)))
Do you have experience designing functions that can filter through a list?
A simpler problem with the same flavor as the original is something like this: design a function that takes a list of numbers and keeps only the even numbers. Would you be able to do that function?
Looking at http://www.ccs.neu.edu/home/matthias/HtDP2e/htdp2e-part2.html and going through its guided exercises may also help.
Two useful tools which should start you on your way:
1) Traversing through a list:
; traverse: takes a list of numbers
; Goes through each element, one-by-one, and alters it
(define traverse
(lambda (the_list)
(if (empty? the_list)
empty
(cons (+ 1 (first the_list))
(traverse (rest the_list))))))
(traverse (cons 3 (cons 4 empty))) returns (cons 4 (cons 5 empty))
2) list?:
(list? (list 1 2 3)) returns #t
(list? 5) returns #f

Lists in scheme

I'm trying to write a function in scheme that takes a list and squares every item on the list, then returns the list in the form (list x y z). However, I'm not sure how to write a code that will do that. So far, I have
(define (square=list list)
(cond
[(empty? list) false]
[else (list (sqr (first a-list))(square-list (rest a-list)))]))
but it returns the list in the form
(cons x (cons y (cons z empty)))
What can I do to make it return the list just in the form (list x y z)? Thanks!
You're almost there -- make sure you understand the difference between cons and list (the textbook How to Design Programs explains this in Section 13. You can find the online copy here).
cons will take an item as its first element and (usually) a (possibly empty) list for the 'rest' part. As an example, (cons 1 empty) has the number 1 as its first element and the empty list as the 'rest'. (cons 1 (cons 2 empty)) has the number 1 as the first element, and (cons 2 empty) as the 'rest'.
list is just an easy shorthand for making lists, taking an arbitrary number of items. Thus:
(list 1 2 3 4 5)
is the same as...
'(1 2 3 4 5)
which is the same as
(cons 1 (cons 2 (cons 3 (cons 4 (cons 5 empty))))).
But be careful. (list 1 (list 2 (list 3))) is not the same as (cons 1 (cons 2 (cons 3 empty))). In fact, it is (cons 1 (cons 2 (cons 3 empty) empty) empty).
If you're still confused, feel free to post a comment.
The problem is that you're using list in the else statement. You are saying build me a list with this value as the first entry, and a list as the second entry.
You want to cons the first entry onto the list created by recursive call.
(list 'a '(b c d))
; gives you
'(a (b c d))
(cons 'a '(b c d))
; gives you
'(a b c d)
This is probably not what your TA is looking for, but I'll throw it in anyway because it may help you grok a tiny bit more of Scheme. The idiomatic (in Scheme) way to write what you are trying to do is to use map:
> (map (lambda (x) (* x x)) '(1 2 3 66 102 10403))
(1 4 9 4356 10404 108222409)
map applies a function (here, (lambda (x) (* x x)) - a nameless function that returns the square of its input) to each element of a list and returns a new list containing all of the results. Scheme's map basically does the same iteration you are doing in your code, the advantage being that by using map you never have to explicitly write such iterations (and, nominally at least, a Scheme implementation might optimize map in some special way, though that's not really that important in most cases). The important thing about map is that it reduces your code to the important parts - this code squares each element of the list, this other code takes the square root of each element, this code adds one to it, etc, without having to repeat the same basic loop iteration code again and again.