Compare/Intersection List of Lists [duplicate] - common-lisp

This question already has an answer here:
Test if array is inside a list in lisp
(1 answer)
Closed 9 months ago.
I wanted to use intersection
to see the intersection of two lists.
While
(intersection (list 1 1) (list 1 1))
works perfectly fine and returns (1 1),
(intersection (list (list 1 2) (list 1 4)) (list (list 1 2) (list 1 5)))
doesnt return me (1 2) but NIL.
Where is my mistake?

intersection takes an optional :test keyword argument to specify what definition of "equality" to use. The default is eql, which compares lists for pointer equality. Since your two lists are actually distinct lists in memory, they're not eql. Use equal to compare lists element-wise.
(intersection (list (list 1 2) (list 1 4)) (list (list 1 2) (list 1 5)) :test #'equal)

Related

How do I filter out the first occurrence from a list in Racket using plai-typed? [duplicate]

This question already has answers here:
Delete element from List in Scheme
(3 answers)
Closed 5 years ago.
In Racket using plai-typed, I am trying to find an element in a list and remove the first one it finds. It will then return the list with the first element it sees removed.
Here is an example:
'(1 2 3 2 5)
Filter out the first 2 and you should get:
'(1 3 2 5)
This is what I am currently doing, but it returns: '(1 3 5)
(filter (lambda (x) (not (equal? x 2))) '(1 2 3 2 5))
So what I am currently doing removes all the occurrences when I just want to remove the first one.
[edit]If you did not want to use that built in function you can do
(define (remove-1st-helper l n)
(cond [(empty? l) empty]
[(= 1 n) l]
[(= 2 (first l)) (remove-1st-helper (rest l)(add1 n))]
[else (cons (first l) (remove-1st-helper (rest l) n))]))
(define (remove-1st-occurence l)
(if (empty? l) empty (remove-1st-helper l 0)))
Don't know Racket, but maybe you can define it as a piece-wise function like this:
-- Define myFilter of an empty list to be empty
myFilter [] = []
-- Decomposes list into first element and rest of list
myFilter (x:xs)
-- Ignore `x` but include the rest of the list
| x == 2 = xs
-- Include x and apply myFilter on xs
| otherwise = x:(myFilter xs)
(Haskell code).

Creating a function to pair the corresponding elements in 2 lists

I am learning to use scheme and practicing by creating functions from practice problems I saw in a book. This one is called zipper.
I have already made the zipper function using recursion with only cons, car, and cdr.
Now I am trying to make this same function again but also using map or fold.
The function takes in two lists and 'zips' them together:
(zip '(1 2 3) '(4 5 6))
==> '((1 4) (2 5) (3 6))
How can I do this using either map or fold?
It may become clearer if the function to be used by map is declared separately:
(define (zip1 x y)
(list x y))
(map zip1 '(1 2 3) '(4 5 6)) ; corresponding elements of 2 lists will be sent to zip1
Since zip1 is only 'list', following also works:
(map list '(1 2 3) '(4 5 6))
Output for both:
'((1 4) (2 5) (3 6))
Hence to do (zip L1 L2), one does not need to write special zip function, one can just do (map list L1 L2).
This can also be used for any number of lists, e.g. (map list L1 L2 L3 L4) which may be an advantage over custom-made zip function made for 2 lists only.
The Racket documentation for map provides the following example:
> (map (lambda (number1 number2)
(+ number1 number2))
'(1 2 3 4)
'(10 100 1000 10000))
'(11 102 1003 10004)
Notice that this is very similar to what you are trying to achieve, but instead of mapping the + function between corresponding elements in two lists, you can map a list function, as follows:
> (map (lambda (number1 number2)
(list number1 number2))
'(1 2 3 4)
'(10 100 1000 10000))
'((1 10) (2 100) (3 1000) (4 10000))
and hence, a zip function becomes:
(define (zip lst1 lst2)
(map
(lambda(elem1 elem2)
(list elem1 elem2))
lst1 lst2))

Scheme: given a list of lists and a permutation, permute

I am practicing for my programming paradigms exam and working through problem sets I come to this problem. This is the first problem after reversing and joining lists recursively, so I suppose there is an elegant recursive solution.
I am given a list of lists and a permutation. I should permute every list including a list of lists with that specified permutation.
I am given an example:
->(permute '((1 2 3) (a b c) (5 6 7)) '(1 3 2))
->((1 3 2) (5 7 6) (a c b))
I have no idea even how to start. I need to formulate the problem in recursive interpretation to be able to solve it, but I can not figure out how.
Well, let's see how we can break this problem down. We are given a list of lists, and a list of numbers, and we want to order each list according to the order specified by the list of numbers:
=>(permute '((1 2 3) (4 5 6)) '(3 2 1))
'((3 2 1) (6 5 4))
We can see that each list in the list of lists can be handled separately, their solutions are unrelated to each other. So we can have a helper permute1 that handles the case of one list, then use map to apply this function to each of the lists (with the same ordering each time):
(define (permute lists ordering)
(map (lambda (xs) (permute1 xs ordering))
lists))
(define (permute1 items ordering)
...)
Now, to calculate (permute1 '(4 5 6) '(3 2 1)), what we mean is:
The first item of the new list will be the 3rd item of items, because the first number in ordering is 3.
The rest of the items of the new list will be determined by using the rest of the numbers in the ordering.
If the ordering is the empty list, return the empty list.
This forms the base case (3), the recursive case (1), and the steps to recur deeper (2). So a sketch of our solution would look like:
(define (permute1 items ordering)
(if (empty? ordering)
'()
(let ([next-item ???])
(??? next-item
(permute1 items (rest ordering))))))
Where the ???s represent getting the item based on the first number in ordering and combining this item with the remainder of the calculation, respectively.
Here's another option, using higher-order functions. This is the idiomatic way to think about a solution in a functional language - we split the problem in sub-problems, solve each one using existing procedures and finally we compose the answer:
(define (atom? x)
(and (not (null? x))
(not (pair? x))))
(define (perm lst order)
(foldr (lambda (idx acc)
(cons (list-ref lst (sub1 idx)) acc))
'()
order))
(define (permute lst order)
(if (atom? lst)
lst
(perm (map (lambda (x) (permute x order)) lst)
order)))
We start by defining atom?, a generic predicate and perm, a helper that will reorder any given list according to the ordering specified in one of its parameters. It uses foldr to build the output list and list-ref to access elements in a list, given its 0-based indexes (that's why we subtract one from each index).
The main permute function takes care of (recursively) mapping perm on each element of an arbitrarily nested input list, so we can obtain the desired result:
(permute '((1 2 3) (a b c) (5 6 7)) '(1 3 2))
=> '((1 3 2) (5 7 6) (a c b))
I am given an example:
(permute ('(1 2 3) '(a b c) '(5 6 7)) '(1 3 2))
((1 3 2) (5 7 6) (a c b))
The syntax you've given isn't correct, and will cause an error, but it's fairly clear what you mean. You want that
(permute '((1 2 3) (a b c) (5 6 7)) '(1 3 2))
;=> ((1 3 2) (5 7 6) (a c b))
Now, it's not clear how you're indicating the permutation. Is '(1 3 2) a permutation because it has some (1-based) indices, and indicates the way to rearrange elements, or is it because it is actually a permutation of the elements of the first list of the first list? E.g., would
(permute '((x y z) (a b c) (5 6 7)) '(1 3 2))
;=> ((x z y) (5 7 6) (a c b))
work too? I'm going to assume that it would, because it will make the problem much easier.
I have no idea even how to start. I need to formulate the problem in
recursive interpretation to be able to solve it, but I can not figure
out how.
You need to write a function that can take a list of indices, and that returns a function that will perform the permutation. E.g,.
(define (make-permutation indices)
…)
such that
((make-permutation '(3 1 2)) '(a b c))
;=> (c a b)
One you have that, it sounds like your permute function is pretty simple:
(define (permute lists indices)
(let ((p (make-permutation indices)))
(p (map p lists))))
That would handle the case you've given in your example, since (map p lists) will return ((1 3 2) (a b c) (5 7 6)), and then calling p with that will return ((1 3 2) (5 7 6) (a c b)). If you need to be able to handle more deeply nested lists, you'll need to implement a recursive mapping function.
Here's my take, which seems to be shorter than the previous examples:
(define (permute lst ord)
(define ord-1 (map sub1 ord)) ; change from 1-based to 0-based indexes
(define (perm elts) ; recursive sub-procedure
(if (list? elts)
(map perm (map (curry list-ref elts) ord-1)) ; list -> recurse
elts)) ; else return unchanged
(perm lst)) ; initial call
testing
> (permute '((1 2 3) (a b c) (5 6 7)) '(1 3 2))
'((1 3 2) (5 7 6) (a c b))
> (permute '((1 (i permute did) 3) (a b (scheme cool is)) (5 6 7)) '(1 3 2))
'((1 3 (i did permute)) (5 7 6) (a (scheme is cool) b))

Lisp Reverse "all" Function

I want to write a function in lisp that reverses all elements from the list using map functions but I don't have any idea how to start this.. I think I have to use the built in reverse function somehow..
For example if I have the list (1 2 3 (4 5 6 (7 8 9))) I would get (((9 8 7) 6 5 4) 3 2 1)
or if I had the list(1 2 3 (4 5) (6 7)) I would get ((7 6) (5 4) 3 2 1) ..
Any help is appreciated!
Just a quick answer, not sure about efficiency/elegancy:
(defun reverse-deeply (list)
(mapcar #'(lambda (li)
(cond
((consp li) (reverse-deeply li))
(t li)))
(reverse list)))
(defun reverse-list (list)
(let ((result nil))
(dolist (e list result)
(push e result))))
Here is a version that works for me in Common-Lisp.
(defun reverse-list (list)
(if (atom list)
list ;; Not actually a list, return the atom
(reverse (mapcar #'reverse-list list)))
;; Testing it out
(reverse-list '((1 2 3) (4 5 (3 6))))
Output:
(((6 3) 5 4) (3 2 1))
Mapcar is a function that takes another function as its first parameter and a list as its second parameter. It then calls that function on each element of the list. It returns a list of all of the answers. So after I use 'mapcar' to reverse all of the sublists, I call 'reverse' again to reverse the bigger list.
The function that it calls on each sublist is 'reverse-list'. This checks if the list is an atom. If it is, then it returns itself. If it's a list, then it calls mapcar again on each element in the list, then reverses the result.

How can I recursively print the elements of a list twice?

I need to write a recursive function that prints out the elements of a list twice. For example, rdouble '(1 2 3) would print (1 1 2 2 3 3) and rdouble'(1 (2 3) 4) would print (1 1 (2 2 3 3) 4 4).
So far I have:
(defun rdouble(struct)
(cond
((atom struct) struct)
(t (cons (rdouble (car struct)) (cons (car struct)
(rdouble (cdr struct))
)))))
This works fine for the first example but prints
(1 1 (2 2 3 3) (2 3) 4 4)
for the second example. How do I continue to print out each element twice but not reprint (2 3)? What am I doing wrong and how can I fix it?
The expression has THREE different cases:
an atom -> return it
a cons with an atom as the CAR -> double it
a cons with a cons as the CAR -> walk down
Your code handles only two cases, where your second case mixes 2 and 3.
the reason it is causing the problems you are experiencing is that given ((1 2) 3) your code recurses into (1 2), which correctly becomes (1 1 2 2) and then adds (1 2) (being the car in the first call) after the (1 1 2 2) giving ((1 1 2 2) (1 2) ...)
what would be best is to make rdouble always return a list, and append those lists together instead of consing them

Resources