Remove from list from other list - lisp

I have list witch contain other lists (2 levels only)
((S U S U R) (S U S R) (S U R))
How to remove the lists from list which contains some pairs, the same combination of 2 element on first ans second position in list or 3th and 4th position (in my example "S U") and to return ((S U S R) (S U R))
I need to transform
((S U S U R) (S U S R) (S U R)) to => ((S U S R) (S U R))
((S U R S U) (S U S R) (S U R)) to => ((S U R S U) (S U S R) (S U R)) - do not change, because here is pairs have S U, R S, U and no S U 2 or more times

REMOVE-IF
(remove-if #'oddp '(1 2 3 4 5))
=> (2 4)
LAMBDA
(funcall (lambda (x) (string x)) :example)
=> "EXAMPLE"
EQUALP
(equalp '(S U) (list 's 'u))
=> T
SUBSEQ
(subseq '(a b c d) 0 3)
=> (A B C)
Careful:
(subseq '(a b c d) 0 10)
=> ERROR
You can also use LENGTH to get the size of a list. You could also use following functions...
NTHCDR
(nthcdr '(s u s u r u) 5)
=> (U)
LDIFF
(let ((list '(a b c d)))
(ldiff list (nthcdr 10 list)))
=> (A B C D)
(let ((list '(a b c d)))
(ldiff list (nthcdr 2 list)))
=> (A B)
What you want to do
You want to remove elements from the input list that satisfy the following predicate: given a list, a subset of this list is equal to (S U) (see comments).
Your code will looks like this:
(defun remove-s-u-at-pos-3 (list)
(remove-if (lambda (...) ...) list))
You need to extract a part of each visited list and compare it to (S U).

Related

LISP - remove duplicates from the given list of atoms

I am trying to remove the duplicate occurrences of the atoms in the given list.
My code is as below -
(defun combine (item List)
(if (member item List)
List (cons item List)))
(defuneliminateDuplicates(L)
(do
((M L) M)
((null L) M)
(setq M (combine (car L) M))
(setq L (cdr L))
))
This code works fine, it removes duplicates from the list -
[3]> (eliminateduplicates '(a b b c a c g a))
(G C B A)
[4]> (eliminateduplicates '(a a a a a a))
(A)
[5]> (eliminateduplicates '(a b c d))
(D C B A)
Here, I want the results to be in the same order as they are present in the given list.
i.e., the result of the (eliminateduplicates '(a b b c a c g a)) should be (B C G A), but not (G C B A)
How can I achieve this? Thanks.
I suggest using a different approach, it's simpler and the result is as expected:
(defun eliminateDuplicates (L)
(cond ((null L) L)
((member (car L) (cdr L))
(eliminateDuplicates (cdr L)))
(t (cons (car L) (eliminateDuplicates (cdr L))))))
For example:
(eliminateDuplicates '(a b b c a c g a))
=> (B C G A)

Return elements if they are in two given lists in lisp

How can i return elements if they are in two given lists?
Example:
L1 = (a b c d e a b c)
L2 = (a d f g k c c)
Result = (a a a c c c c d d)
I want to remove elements that arent in both lists and, then, append the resultant lists
You can start with a hash table, mapping a list element to a pair, first being elements from the first list, second - elements from the second. Then you collect the elements:
(defun common-elements (l1 l2 &key (test 'eql))
(let ((ht (make-hash-table :test test)) ret)
(dolist (e l1)
(let ((pair (gethash e ht)))
(if pair
(push e (car pair))
(setf (gethash e ht) (cons (list e) nil)))))
(dolist (e l2)
(let ((pair (gethash e ht)))
(when pair ; no need to store e when it is not in l1
(push e (cdr pair)))))
(maphash (lambda (e pair)
(declare (ignore e))
(when (cdr pair) ; we know (car pair) is non-nil
(setq ret (nconc (car pair) (cdr pair) ret))))
ht)
ret))
(common-elements '(a b c d e a b c) '(a d f g k c c))
==> (A A A C C C C D D)
Note that the order in which the list elements are returned is not defined.

How can i get all possible combinations of sets and subsets of a list that satisfy conditions with Common Lisp

For a list of elements for L = (A B C D), to generate all the combinations possible of elements that satisfy the lexicographical order of elements (A < B < C < D ...< Z), will be generated all combination.
For example L = (A B C D) well output (A), (B), (C), (D), (A B), (B C), (C D), (A B C), (B C D), (A B C D).
The lexicographical (not lexicological) order can be obtained through the following function that checks if the list a precedes the list b in lexicographical order:
(defun lex<= (a b)
(or (null a)
(and b
(string<= (car a) (car b))
(lex<= (cdr a) (cdr b)))))
so, you could produce all the combinations, like in the answer of coredump, and then sort them with (sort result #'lex<=).
Looks like you just write simple function to get power set of your list, and then just remove an empty set, and order it in any way you want.
(defun powerset (lst)
(if lst (mapcan (lambda (el) (list (cons (car lst) el) el))
(powerset (cdr lst)))
'(())))
CL-USER> (powerset '(A B C D))
((A B C D) (B C D) (A C D) (C D) (A B D) (B D) (A D) (D) (A B C) (B C) (A C)
(C) (A B) (B) (A) NIL)
To get exactly your describet output you can remove NIL and reverse it:
CL-USER> (reverse (remove nil (powerset '(A B C D))))
((A) (B) (A B) (C) (A C) (B C) (A B C) (D) (A D) (B D) (A B D) (C D) (A C D)
(B C D) (A B C D))
Is this what you want?
UPDATE. Sorry, didn't mention that you want it sorte in another way. You should resort it:
CL-USER> (sort
(reverse
(remove nil
(powerset '(A B C D))))
#'< :key #'length)
((A) (B) (C) (D) (A B) (A C) (B C) (A D) (B D) (C D) (A B C) (A B D) (A C D)
(B C D) (A B C D))
And this is another, more imparative solution, using loop macro, doing what you described:
(defun combinations (lst)
(loop :for i :below (expt 2 (length lst))
:when (loop :for j :below i :for el :in lst if (logbitp j i) :collect el)
:collect it :into result
:finally (return (sort result #'< :key #'length))))
CL-USER> (combinations '(A B C D E))
((A) (B) (C) (D) (E) (A B) (A C) (B C) (A D) (B D) (C D) (A E) (B E) (C E)
(D E) (A B C) (A B D) (A C D) (B C D) (A B E) (A C E) (B C E) (A D E) (B D E)
(C D E) (A B C D) (A B C E) (A B D E) (A C D E) (B C D E) (A B C D E))

drRacket structure error

When I write these codes and program gives error;
"leaf-name: expects a leaf, given empty"
(define-struct leaf (parent children name level-of-vertex))
(define A (make-leaf empty '(B C D) 'A 1))
(define B (make-leaf A '(E F) 'B 2))
(define C (make-leaf A 'G 'C 2))
(define D (make-leaf A '(H J) 'D 2))
(define E (make-leaf B empty 'E 3))
(define F (make-leaf B '(K L) 'F 3))
(define G (make-leaf C empty 'G 3))
(define H (make-leaf D empty 'H 3))
(define J (make-leaf D empty 'J 3))
(define K (make-leaf F empty 'K 4))
(define L (make-leaf F empty 'L 4))
(define binarytree (list A B C D E F G H J K L empty))
(define (findchild child)
(display (leaf-name (leaf-children child))))
(findchild E)
How I can solve this error?
Change
(define binarytree (list A B C D E F G H J K L empty))
to
(define binarytree (list A B C D E F G H J K L))
After the above change, note that that:
(define E (make-leaf B empty 'E 3))
Thus
(leaf-children E)
empty
That's why (leaf-name (leaf-children E))) becomes (leaf-name empty) and you get the error.
I imagine (leaf-children node) would evaluate to a list of objects and not a leaf. In fact, E doesn't have children.
When you select parent you use an actual object, but with children you have quotes list of symbols as children. Thus they are not a list of objects but symbols.
Without mutation you can either point upward or downward. With both you need to do one then the other by mutation. Perhaps from leaf to root. The binarytree is strange since I'd guess the full binary tree is supposed to be A.

Q about Problem 19-2 in "Lisp" by Winston and Horn

Problem 19-2 in "Lisp" by Winston and Horn states,
In depth-first search, all of the
partial paths in the queue at a given
point in the search are related to
one another in a simple way: each is
the extension by one node of the
partial path after it in the queue.
The queue might, for example, look
like this:
((D C B A) (C B A) (B A) (A))
However, I don't see how that's the case. For example, I get output
like the following:
(depth-first 's 'f)
queue: ((S))
(S)
queue: ((A S) (D S))
(S A)
queue: ((B A S) (D A S) (D S))
(S A B)
queue: ((C B A S) (E B A S) (D A S) (D S))
(S A B C)
queue: ((E B A S) (D A S) (D S))
(S A B E)
queue: ((D E B A S) (F E B A S) (D A S) (D S))
(S A B E D)
queue: ((F E B A S) (D A S) (D S))
(S A B E F)
where I put a print statement at the beginning of the routine:
(defun depth-first (start finish &optional
(queue (list (list start))))
(format t "~%queue: ~a" queue)
(cond ((endp queue) nil)
((eq finish (first (first queue)))
(reverse (first queue)))
(t (depth-first
start
finish
(append (extend (first queue))
(rest queue))))))
In this case, no partial path in the queue is the extension by one
node of the partial path after it in the queue.
Is this a misprint in the exercise or is there some input that does
actually give the queue he gives?
See answer by Pascal Bourguignon.