This must be very easy to accomplish but I am new to racket and dont know how:
I have a list (1 2 3 4) and would like to convert it into (1)(2)(3)(4)
Or is there a way to build it as (1)(2)(3)(4). I am using
cons '(element) call-function
to build it inside a function (recursively)
Try this:
(map list '(1 2 3 4))
From your text, I see that you do '(element). Problem with that is that everything which is quoted is never anything but what you see. Thus if element happens to be a variable it won't be expanded because of the quote.
The right way to get a list with one element would be to use list. eg. (list element) to get whatever the variable element to be the one element in your list. However, you won't need this in a roll-your-own recursive procedure:
(define (listify lst)
(if (null? lst) ; if lst is null we are done
'() ; evaluate to the empty list
(cons (list (car lst)) ; else we make a list with the first element
(listify (cdr lst))))) ; and listify the rest of the list too
Most of the procedure now is facilitating going through the argument, but since it's a common thing to do we can use higher order procedures with foldr so that you only concentrating on what is going to happen with the element in this chain in correspondence with the rest of the process:
(define (listify lst)
(foldr (lambda (e acc)
(cons (list e) ; chain this element wrapped in a list
acc)) ; with the result from the rest of the list
'() ; initiate with an empty list
lst)) ; go through lst
Of course, since we do something with each element in a list and nothing fancy by using map we only need to supply what to do with each element rather telling how to join the chains in the list together as well.
(define (listify lst)
(map list lst)) ; make a new list by applying a list of each element
It's actually a single argument version of zip:
(require srfi/1)
(zip '(1 2 3 4)) ; ==> ((1) (2) (3) (4))
(zip '(1 2 3) '(a b c)) ; ==> ((1 a) (2 b) (3 c))
There you go. As simple as it can get.
Related
"Implement unique, which takes in a list s and returns a new list containing the same elements as s with duplicates removed."
scm> (unique '(1 2 1 3 2 3 1))
(1 2 3)
scm> (unique '(a b c a a b b c))
(a b c)
What I've tried so far is:
(define (unique s)
(cond
((null? s) nil)
(else (cons (car s)(filter ?)
This question required to use the built-in filter function. The general format of filter function is (filter predicate lst), and I was stuck on the predicate part. I am thinking it should be a lambda function. Also, what should I do to solve this question recursively?
(filter predicate list) returns a new list obtained by eliminating all the elements of the list that does not satisfy the predicate. So if you get the first element of the list, to eliminate its duplicates, if they exists, you could simply eliminate from the rest of the list all the elements equal to it, something like:
(filter
(lambda (x) (not (eqv? x (first lst)))) ; what to maintain: all the elements different from (first lst)
(rest lst)) ; the list from which to eleminate it
for instance:
(filter (lambda (x) (not (eqv? x 1))) '(2 1 3 2 1 4))
produces (2 3 2 1 4), eliminating all the occurrences of 1.
Then if you cons the first element with the list resulting from the filter, you are sure that there is only a “copy” of that element in the resulting list.
The last step needed to write your function is to repeat recursively this process. In general, when you have to apply a recursive process, you have to find a terminal case, in which the result of the function can be immediately given (as the empty list for lists), and the general case, in which you express the solution assuming that you have already available the function for a “smaller” input (for instance a list with a lesser number of elements).
Consider this definition:
define (unique s)
(if (null? s)
'()
(cons (first s)
(filter
(lambda (x) (not (eq? x (first s))))
(unique (rest s))))))
(rest s) is a list which has shorter than s. So you can apply unique to it and find a list without duplicates. If, from this list, you remove the duplicates of the first element with filter, and then cons this element at the beginning of the result, you have a list without any duplicate.
And this is a possibile solution to your problem.
For my programming languages class I'm supposed to write a function in Scheme to reverse a list without using the pre-made reverse function. So far what I got was
(define (reverseList lst)
(COND
((NULL? lst) '())
(ELSE (CONS (reverseList(CDR lst)) (CAR lst)))
))
The problem I'm having is that if I input a list, lets say (a b c) it gives me (((() . c) . b) . a).
How am I supposed to get a clean list without multiple sets of parenthesis and the .'s?
The problem with your implementation is that cons isn't receiving a list as its second parameter, so the answer you're building isn't a proper list, remember: a proper list is constructed by consing an element with a list, and the last list is empty.
One possible workaround for this is to use a helper function that builds the answer in an accumulator parameter, consing the elements in reverse - incidentally, this solution is tail recursive:
(define (reverse lst)
(reverse-helper lst '()))
(define (reverse-helper lst acc)
(if (null? lst)
acc
(reverse-helper (cdr lst) (cons (car lst) acc))))
(reverse '(1 2 3 4 5))
=> '(5 4 3 2 1)
You are half way there. The order of the elements in your result is correct, only the structure needs fixing.
What you want is to perform this transformation:
(((() . c) . b) . a) ; input
--------------------
(((() . c) . b) . a) () ; trans-
((() . c) . b) (a) ; for-
(() . c) (b a) ; mation
() (c b a) ; steps
--------------------
(c b a) ; result
This is easy to code. The car and cdr of the interim value are immediately available to us. At each step, the next interim-result is constructed by (cons (cdr interim-value) interim-result), and interim-result starts up as an empty list, because this is what we construct here - a list:
(define (transform-rev input)
(let step ( (interim-value input) ; initial set-up of
(interim-result '() ) ) ; the two loop variables
(if (null? interim-value)
interim-result ; return it in the end, or else
(step (car interim-value) ; go on with the next interim value
(cons ; and the next interim result
(... what goes here? ...)
interim-result )))))
interim-result serves as an accumulator. This is what's known as "accumulator technique". step represents a loop's step coded with "named-let" syntax.
So overall reverse is
(define (my-reverse lst)
(transform-rev
(reverseList lst)))
Can you tweak transform-rev so that it is able to accept the original list as an input, and thus skip the reverseList call? You only need to change the data-access parts, i.e. how you get the next interim value, and what you add into the interim result.
(define (my-reverse L)
(fold cons '() L)) ;;left fold
Step through the list and keep appending the car of the list to the recursive call.
(define (reverseList lst)
(COND
((NULL? lst) '())
(ELSE (APPEND (reverseList(CDR lst)) (LIST (CAR lst))))
))
Instead of using cons, try append
(define (reverseList lst)
(if (null? lst)
'()
(append (reverseList (cdr lst)) (list (car lst)) )
)
)
a sample run would be:
1]=> (reverseList '(a b c 1 2 + -))
>>> (- + 2 1 c b a)
car will give you just one symbol but cdr a list
Always make sure that you provide append with two lists.
If you don't give two lists to the cons it will give you dotted pair (a . b) rather than a list.
See Pairs and Lists for more information.
I am learning a course of Scheme and have to do the following task. I have to write a function that gets two lists A and B in the same length and returns one list that every item inside is a list of two items - one from A and second from B.
For example the function gets '( 1 2 3) and '(4 5 6) and returns '((1 4)(2 5)(3 6)).
I can do that using map like this:
(define (func lst1 lst2) (map (lambda(x y) (list x y)) lst1 lst2))
But the the question is to do that by foldr and without explicit recursion.
Can anyone please help me? I have no idea how to do that....
Thanks!
The trick is knowing what to pass as a function parameter, here's how:
(define (func l1 l2)
(foldr (lambda (e1 e2 acc)
(cons (list e1 e2) acc))
'()
l1 l2))
Notice that we're passing two lists at the end of foldr, so the lambda expects three parameters: the current element from the first list (e1), the current element from the second list (e2) and the accumulated output (acc), which starts with value '(). The rest is easy, just build the output along using cons and list. It works as expected:
(func '(1 2 3) '(4 5 6))
=> '((1 4) (2 5) (3 6))
I am trying to write a function called unzip that takes a list and evaluates to a list of two lists that have alternating elements of the original list.
so far this is what i have:
(define (unzip lst)
(if (null? lst)
'()
(...
this is how it should work:
(unzip '(1 a 2 b 3 c)) should evaluate to ((1 2 3) (a b c))
What you have is on the wrong track, sorry. (Think about what the result should be if given an empty input.) Similar to my answer to your last question, here's a skeleton solution:
(define (unzip l)
(if (null? l) ???
(let ([next (unzip ???)])
(list (cons ??? ???) ???))))
Fill in the ???s appropriately. (Yes, my solution is tested and works for both odd and even inputs.)
Hi I am trying to write a program where given a list of lists check to see if they are equal in size and return #t if they are.
So for example if i were to write (list-counter? '((1 2 3) (4 5 6) (7 8 9))) the program would return #t, and (list-counter? '((1 2 3) (4 5 6) (7 8))) would return #f.
SO far this is what I have done:
(define list-counter?
(lambda (x)
(if (list? x)
(if (list?(car x))
(let (l (length (car x))))
(if (equal? l (length(car x))))
(list-counter?(cdr x))
) ) ) ) )
I think where I am going wrong is after I set the length of l to the length of the first list. Any help would be appreciated.
There are several ways to solve this problem. For instance, by hand and going step-by-step:
(define (all-lengths lists)
(if (null? lists)
'()
(cons (length (car lists))
(all-lengths (cdr lists)))))
(define (all-equal? head lengths)
(if (null? lengths)
true
(and (= head (car lengths))
(all-equal? head (cdr lengths)))))
(define (list-counter? lists)
(let ((lengths (all-lengths lists)))
(all-equal? (car lengths) (cdr lengths))))
Let me explain the above procedures. I'm dividing the problem in two steps, first create a new list with the lengths of each sublist - that's what all-lengths does. Then, compare the first element in a list with the rest of the elements, and see if they're all equal - that's what all-equal? does. Finally, list-counter? wraps it all together, calling both of the previous procedures with the right parameters.
Or even simpler (and shorter), by using list procedures (higher-order procedures):
(define (list-counter? lists)
(apply = (map length lists)))
For understanding the second solution, observe that all-lengths and all-equal? represent special cases of more general procedures. When we need to create a new list with the result of applying a procedure to each of the elements of another list, we use map. And when we need to apply a procedure (= in this case) to all of the elements of a list at the same time, we use apply. And that's exactly what the second version of list-counter? is doing.
You could write an all-equal? function like so:
(define (all-equal? list)
;; (all-equal? '()) -> #t
;; (all-equal? '(35)) -> #t
;; (all-equal? '(2 3 2)) -> #f
(if (or (null? list) (null? (cdr list)))
#t
(reduce equal? list)
))
then do:
(all-equal? (map length listOfLists))
Alternatively you can do:
(define (lists-same-size? list-of-lists)
(if (== (length listOfLists) 0)
#t
(let*
(( firstLength
(length (car listOfLists)) )
( length-equal-to-first?
(lambda (x) (== (length x) firstLength)) )
)
(reduce and #t (map length-equal-to-first? listOfLists))
)
)))
What this says is: if the list length is 0, our statement is vacuously true, otherwise we capture the first element of the list's length (in the 'else' part of the if-clause), put it in the closure defined by let's syntactic sugar (actually a lambda), and use that to define an length-equal-to-first? function.
Unfortunately reduce is not lazy. What we'd really like is to avoid calculating lengths of lists if we find that just one is not equal. Thus to be more efficient we could do:
...
(let*
...
( all-match? ;; lazy
(lambda (pred list)
(if (null? list)
#t
(and (pred (first list)) (all-match? (cdr list)))
;;^^^^^^^^^^^^^^^^^^^ stops recursion if this is false
)) )
)
(all-match? length-equal-to-first? listOfLists)
)
)))
Note that all-match? is already effectively defined for you with MIT scheme's (list-search-positive list pred) or (for-all? list pred), or in Racket as andmap.
Why does it take so long to write?
You are forced to write a base-case because your reduction has no canonical element since it relies on the first element, and list manipulation in most languages is not very powerful. You'd even have the same issue in other languages like Python. In case this helps:
second method:
if len(listOfLists)==0:
return True
else:
firstLength = len(listOfLists[0])
return all(len(x)==firstLength for x in listOfLists)
However the first method is much simpler to write in any language, because it skirts this issue by ignoring the base-cases.
first method:
if len(listOfLists)<2:
return True
else:
return reduce(lambda a,b: a==b, listOfLists)
This might sound a bit weird, but I think it is easy.
Run down the list, building a new list containing the length of each (contained) list, i.e. map length.
Run down the constructed list of lengths, comparing the head to the rest, return #t if they are all the same as the head. Return false as soon as it fails to match the head.