I am trying to obtain a cross product between two lists. I can see that the problem is that it's trying to append (CP2 T1 T2) with (CP2 T1 T3). I have thought of other ways, such as (CP2 (CP2 T1 T2) ...), but again, the ellipses just expand into an undesired output.
(define-syntax CP
(syntax-rules ()
((CP T1 T2 ...)
(append (CP2 T1 T2) ...)
)
)
)
(define (CP2 T1 T2)
(foldr append '() (map (λ(x)
(map (λ(y) (append x y)) T2))
T1))
)
Is it not possible doing it this way at all?
Thank you.
It can be done with one of the for loops also ( http://docs.racket-lang.org/reference/for.html ):
(define (myproduct l1 l2)
(for*/list ((i l1)(j l2))
(list i j)))
(myproduct '(1 2 3) '(a b c))
Ouput:
'((1 a) (1 b) (1 c) (2 a) (2 b) (2 c) (3 a) (3 b) (3 c))
Related
I have a list
'((1 2 (A B C)) (2 3 (B C D)) (4 5 (C D F)))
I want to process the elements in the inner list, (in this case, I want to change (A B C) and other lists to (M M M)).
I wrote a code (process lst), which will do this task for the inner list.
(defun process (lst)
(cond
((null lst) '())
(T (cons 'M (process (cdr last))))))
And when I call from the main function,
(defun iterate-list (lst)
(cond
((null lst) '())
((listp (car lst))
(cons (process (car lst))
(iterate-list (cdr lst))))
(T
(cons (car lst)
(iterate-list (cdr lst))))))
I am getting ((M M M) (M M M) (M M M)) instead of ((1 2 (M M M)) (2 3 (M M M)) (4 5 (M M M))).
But when I use the same function, with just (cons (car lst)) (iterate-list (cdr lst))) in the second condition (listp (car lst)), I am getting the correct answer, that is
'((1 2 (A B C)) (2 3 (B C D)) (4 5 (C D F)))
I don't know where I am making the mistake.
If you want something practical, I would suggest the subst function from the Common LISP Standard Library.
http://clhs.lisp.se/Body/f_substc.htm
(setq tree1 '(1 (1 2) (1 2 3) (1 2 3 4))) => (1 (1 2) (1 2 3) (1 2 3 4))
(subst "two" 2 tree1) => (1 (1 "two") (1 "two" 3) (1 "two" 3 4))
(subst "five" 5 tree1) => (1 (1 2) (1 2 3) (1 2 3 4))
You can also add you own equality function by using the variant subst-if with a lambda function.
NB. You need to rename last to lst in process.
I am getting ((M M M) (M M M) (M M M)) instead of ((1 2 (M M M)) (2 3 (M M M)) (4 5 (M M M))).
The code works, but not that at the depth you want:
(process '(a b c d))
=> (M M M M)
(iterate-list '(1 2 (A B C)))
=> (1 2 (M M M))
In order to process all lists in your root list, you could do this:
(mapcar #'iterate-list '((1 2 (A B C))
(2 3 (B C D))
(4 5 (C D F))))
=> ((1 2 (M M M)) (2 3 (M M M)) (4 5 (M M M)))
I have the following task:
To build the function (REMOVE EL), that removes given atom or list from another list, and this should apply on each level of the list
Example :
L=(A B A (B A C X ) X B)
(REMOVE A L ) -> (B (B C X) X B)
I wrote the following code :
(defun removeel(el tree)
(mapcan (lambda(subtree)
(cond ((null subtree) (list nil))
((consp subtree) (list (removeel el subtree)))
((eql subtree el) nil)
(t (list subtree))))
tree))
The problem is that when I remove atom, it works excellent
(removeel 'B' (A B A (B A C X ) X B))
(A A (A C X) X)
But it doesn't work If I want to remove a list
(removeel '(B A C X) ' (A B A (B A C X ) X B))
(A B A (B A C X) X B)
What should be done to make it to remove lists too ?
the simplest way would be to introduce optional equality test function, as in remove standard procedure.
it could look this way:
(defun rem-rec (item data &key (test #'eql))
(mapcar (lambda (x) (if (listp x)
(rem-rec item x :test test)
x))
(remove item data :test test)))
CL-USER> (rem-rec 1 `(1 2 (3 4 (1 2 3)) (1 (1 2 3) 3 4)))
;;=> (2 (3 4 (2 3)) ((2 3) 3 4))
for lists equality you can use equal (or equalp or anything more specific)
CL-USER> (rem-rec '(1 2 3) '(1 2 (3 4 (1 2 3)) (1 (1 2 3) 3 4)) :test #'equal)
;;=> (1 2 (3 4) (1 3 4))
I am doing Exercise 1.3 from SICP.
My code is the following:
#lang racket
(require sicp)
(define (square a)
(* a a)
)
(define (sum-of-squares a b)
(+ (square a) (square b) )
)
(define (max a b)
(cond ((>= a b) a)
(else b)
)
)
(define (sum-of-biggest-squares a b c )
(cond ((>= a b)
(sum-of-squares a (max b c) )
(sum-of-squares b (max a c) )
)
)
)
(sum-of-biggest-squares 5 7 10)
Surprisingly, the Racket interpreter does
not print any result for the above. The interpreter
works fine for other values. But for
this set of three values its not
working.
When I try to add an else statement
like the following:
(else (sum-of-squares b (max a c) ) )
The interpreter says:
exercise_1-3.rkt:23:10: else: not allowed as an expression
in: (else (sum-of-squares b (max a c)))
You have a couple of syntax errors in function sum-of-biggest-squares: a parenthesis should be added to close the first cond clause, and else should be added to the second one:
(define (sum-of-biggest-squares a b c)
(cond ((>= a b) (sum-of-squares a (max b c)))
(else (sum-of-squares b (max a c)))))
Note that the way in which you format the code, so different from the current common conventions, makes very difficult to read it and easy to introduce syntax errors.
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).
I am new to lisp programming and i am trying to think about the below operation.
(extract '(0 1 0) '(a b c)) give us '(a b a)
(extract '(1 1 1 ) '(a b c)) gives us '(b b b)
how can i think about this and how to solve it.
As Chris Jester-Young described, it just returns elements from second list at indexes in first list. Writing such a function is very easy:
(defun extract (list-1 list-2)
(mapcar (lambda (n) (nth n list-2)) list-1))
CL-USER>(extract '(0 1 0) '(a b c))
(A B A)
CL-USER>(extract '(1 1 1 ) '(a b c))
(B B B)
If there no such index, it'll give you NIL in that place.
CL-USER> (extract '(1 100 1 ) '(a b c))
(B NIL B)
But this won't work on nested structures (trees). If you want it to return elements of list-2 shaped in the structure of list-1, you can use a simple maptree helper function, then do the same thing:
(defun maptree (fn tree)
(cond
((null tree) tree)
((atom tree) (funcall fn tree))
(t (cons
(maptree fn (first tree))
(maptree fn (rest tree))))))
(defun extract* (list-1 list-2)
(maptree (lambda (n)
(nth n list-2)) list-1))
CL-USER> (extract* '(3 (2 1 (0))) '(a b c d))
(D (C B (A)))
(extract a b) returns a copy of a where each element is replaced by the element of b in that position.