I have a file which name is dictionary.lisp. That includes some words like
(defparameter *dictionary* '(
(a b a)
(a b a d i)
.
.
)
I try to find them as a list. I tried the followings
[5]> (find '((a b a d i)) *dictionary* :test 'equal )
NIL
[6]> (find '((a b a d i)) *dictionary* :test #'equalp )
NIL
[7]> (member '((a b a d i)) *dictionary* :test 'equal )
NIL
[8]> (member '((a b a d i)) *dictionary* :test #'equalp )
NIL
[9]> (find '((a b a d i)) *dictionary* :test #'subsetp )
NIL
Is there any lisp function that can return non-nil?
You need to use equal or equalp as your test, which you're doing in four of your examples. You also need to search for something that's actually in the list. For instance, The dictionary you've described contains the list of five symbols (a b a d i) as an element, but not the list ((a b a d i)) (which is a list containing a single element, and that element is a list of five symbols). This means you'd do (find '(a b a d i) … :test 'equal):
CL-USER> (defparameter *dictionary* '((a b a)
(a b a d i)))
*DICTIONARY*
CL-USER> (find '((a b a d i)) *dictionary* :test 'equal)
NIL
CL-USER> (find '(a b a d i) *dictionary* :test 'equal)
(A B A D I)
CL-USER> (find '(f o o) *dictionary* :test 'equal)
NIL
CL-USER 25 > (defparameter *dictionary* '((a b a) (a b a d i)))
*DICTIONARY*
CL-USER 26 > (defun my-find (list0 list1)
(and (find (first list0) list1 :test #'equal)
t))
MY-FIND
CL-USER 27 > (my-find '((a b a d i)) *dictionary*)
T
It just does not look like it will make much sense.
Related
A library function returns seven values. I only need the first four and the last one. Is there a more elegant way than:
(multiple-value-bind (a b c d e f g)
(library-call)
(declare (ignore e f))
(rest-of-code a b c d g))
You can keep a "mvb" look and feel with the metabang-bind library (a let on steroïds which allows more destructing and bindings) and use the _ placeholder.
Below, we "bind" on a multiple-value with `(:values …):
(metabang.bind:bind (((:values _ b) (values 1 2)))
b)
;; => 2
You can use MULTIPLE-VALUE-LIST and SUBSEQ:
(defun library-call () (apply #'values '(a b c d e f g)))
(defun rest-of-code (&rest rest)
(print rest))
(let ((lst (multiple-value-list (library-call))))
(apply #'rest-of-code
`(,#(subseq lst 0 4) ,(car (last lst)))))
=> (A B C D G)
I think the only way to do this without consing some intermediate structure is what you suggest. Of course this is easy to define syntax for if it happens a lot.
As an example here's a thing called mvb which is like multiple-value-bind except that variables whose name is "_" are ignored (so this doesn't rely on exporting a symbol _). This relies on org.tfeb.hax.collecting: it could be redone not to.
(defmacro mvb (bindings form &body forms)
(multiple-value-bind (vars ignores)
(with-collectors (var ignore)
(let ((i 1))
(dolist (b bindings)
(typecase b
(symbol
(cond
((string= (symbol-name b) "_")
(let ((g (make-symbol (format nil "_~D" i))))
(incf i)
(var g)
(ignore g)))
(t
(var b))))
(t
(error "mutant binding ~A" b))))))
`(multiple-value-bind ,vars ,form
,#(if ignores `((declare (ignore ,#ignores))))
,#forms)))
With this your call would be
(mvb (a b c d _ _ g)
(library-call)
(rest-of-code a b c d g))
Which turns into
(multiple-value-bind (a b c d #:|_1| #:|_2| g)
(library-call)
(declare (ignore #:|_1| #:|_2|))
(rest-of-code a b c d g))
Note that my binding macro now supports something similar to this, using nil as the 'don't bind anything' placeholder:
(binding
(bind/values (a nil b) (values 1 2 3))
(print a)
(bind c (+ a b))
c)
nil is a nice choice I think because it can't break any existing program since nil can't be bound.
I am trying to write a function in Scheme that returns all rotations of a given list. For example, (rotate '(a b c d e)) should return ((a b c d e) (b c d e a) (c d e a b) (d e a b c) (e a b c d)) (in some order).
I am not sure this would work:
(define (make-rotate alphabet) (lambda (x) (+ x alphabet)))
(define (same-arg-twice fn) (lambda (arg) (fn arg arg)))
(define (flip fn) (lambda (a b c d e) (fn b c d e a) (fn c d a e b) (fn d e a b c) (fn e a b c d)
(define (flip fn)
(lambda (3 9 5 8 2 4 7) (fn 9 4 3 2 4 7 8) (fn 3 2 4)
Start with a function that rotates a list once.
That is, it takes the list's first element and puts it at the back instead.
(define (rotate-once ls)
(append (cdr ls) (list (car ls))))
Test:
> (rotate-once '(a b c))
'(b c a)
Looks good.
Now we can use this on an already rotated list to produce the next rotation.
> (rotate-once (rotate-once '(a b c)))
'(c a b)
We could almost write this recursive procedure
(define (rotate ls)
(if (...)
'()
(cons ls (rotate (rotate-once ls)))))
but there is no useful condition for terminating the recursion.
We could depend on the length of the list, but I did this instead: make a helper function and pass it the list of elements that haven't been moved around yet.
When that list is empty, we're done.
(define (rotate-helper ls remaining)
(if (null? remaining)
'()
(cons ls (rotate-helper (rotate-once ls) (cdr remaining)))))
and now we can define
(define (rotate ls) (rotate-helper ls ls))
and
> (rotate '(a b c d e))
'((a b c d e) (b c d e a) (c d e a b) (d e a b c) (e a b c d))
(define (rotate lst)
(for/list ((_ lst))
(let ((tmp lst))
(set! lst (append (cdr lst) (list (car lst))))
tmp)))
> (rotate '(a b c d e))
'((a b c d e) (b c d e a) (c d e a b) (d e a b c) (e a b c d))
or:
(define (one-rotate lst)
(append (cdr lst) (list (car lst))))
(define (rotate lst)
(for/list ((_ lst))
(let ((tmp lst))
(set! lst (one-rotate lst))
tmp)))
The procedure below takes two lists and returns their union as an ordered list.
(defun stable-union (lst1 lst2)
(cond ((null lst1) lst2)
((null lst2) lst1)
((and (null lst1) (null lst2)) nil)
(t
(let ((el1 (car lst1))
(el2 (car lst2)))
(cond ((string= el1 el2)
(cons el1
(stable-union (cdr lst1) (cdr lst2))))
((string< el1 el2)
(cons el1
(stable-union (cdr lst1) lst2)))
(t
(cons el2
(stable-union lst1 (cdr lst2)))))))))
It works for some examples and fails for others. For example:
STABLE-UNION: (STABLE-UNION '(A B C) '(B A D)) failed:
Expected (A B C D) but saw (A B A C D)
STABLE-UNION: (STABLE-UNION '(A B C) '(A D B E)) failed:
Expected (A B C D E) but saw (A B C D B E)
STABLE-UNION: (STABLE-UNION '(C B A) '(A E B D)) failed:
Expected (C B A E D) but saw (A C B A E B D)
Can you guide me as to where I am making mistakes in my code? Thank you so much.
The above function works only for lists that are composed by symbols already lexicographically ordered. So, for instance, it works correctly for '(A B C) '(A B D), but not for '(A B C) '(B A D).
There are several ways of correcting it. The simplest one is to call it by sorting (with stable-sort) the two arguments, for instance:
(defun stable-union-general (lst1 lst2)
(stable-union (stable-sort lst1 #'string<) (stable-sort lst2 #'string<)))
(stable-union-general '(A B C) '(B A D))
(A B C D)
Another, less efficient, way is to change the algorithm by taking into account unordered lists.
Finally note that the third branch of the outer conditional is never statisfied: ((and (null lst1) (null lst2)) nil)
This is because, in this case, the first branch is true and the function returns nil.
(defun split-list (L)
(if (endp L)
'(nil nil)
(let ((x (split-list (cdr L))))
(list (cons (car L) (cadr x))(car X))
)))
This is the code which I have. It works fine:
(split-list '(1 2 3 4 5 6))
((1 3 5) (2 4 6))
But I need an explanation on the recursion part.
When we call the function (split-list (cdr L)) I am sure that it goes from 123456 to 23456. (car L) is 1
and (cadr X) is 3 but how did 5 came there ?
when function did
(split-list (cdr L)) didn't the x became 3456 and (cadr x) should be 4 ? which is wrong and same with other half. (car x) should be 3 now which is wrong.
Could anyone please explain ?
I would rewrite a recursive split-list as this:
(defun split-list (list)
(if (endp list)
(values nil nil)
(multiple-value-bind (split1 split2)
(split-list (rest list))
(values (cons (first list) split2)
split1))))
Above uses multiple values. The function returns the split result as two values. We also replace car with first and cdr with rest. The are just better names, but have the same functionality. multiple-value-bind binds the the two values of the recursive split-list call to the variables split1 and split2. The function values returns its two arguments as two values.
In the example below, you can see that the function indeed returns two values:
CL-USER 20 > (split-list '(a b c d e f))
(A C E)
(B D F)
You can trace its execution:
CL-USER 21 > (trace split-list)
(SPLIT-LIST)
CL-USER 22 > (split-list '(a b c d e f))
0 SPLIT-LIST > ((A B C D E F))
1 SPLIT-LIST > ((B C D E F))
2 SPLIT-LIST > ((C D E F))
3 SPLIT-LIST > ((D E F))
4 SPLIT-LIST > ((E F))
5 SPLIT-LIST > ((F))
6 SPLIT-LIST > (NIL)
6 SPLIT-LIST < (NIL NIL)
5 SPLIT-LIST < ((F) NIL)
4 SPLIT-LIST < ((E) (F))
3 SPLIT-LIST < ((D F) (E))
2 SPLIT-LIST < ((C E) (D F))
1 SPLIT-LIST < ((B D F) (C E))
0 SPLIT-LIST < ((A C E) (B D F))
(A C E)
(B D F)
I came across Pascal Bourguignon's solutions of the 99 Lisp problems and was wondering if his recursive solution of problem 27 using a nested mapcan-mapcar-construct could also be written using nested loops.
His solution is definitely very elegant:
(defun group (set sizes)
(cond
((endp sizes)
(error "Not enough sizes given."))
((endp (rest sizes))
(if (= (first sizes) (length set))
(list (list set))
(error "Cardinal mismatch |set| = ~A ; required ~A"
(length set) (first sizes))))
(t
(mapcan (lambda (combi)
(mapcar (lambda (group) (cons combi group))
(group (set-difference set combi) (rest sizes))))
(combinations (first sizes) set)))))
The function combinations is defined here as:
(defun combinations (count list)
(cond
((zerop count) '(())) ; one combination of zero element.
((endp list) '()) ; no combination from no element.
(t (nconc (mapcar (let ((item (first list)))
(lambda (combi) (cons item combi)))
(combinations (1- count) (rest list)))
(combinations count (rest list))))))
I started with a simple approach:
(defun group-iter (set sizes)
(loop :with size = (first sizes)
:for subgroup :in (combination size set)
:for remaining = (set-difference set subgroup)
:collect (list subgroup remaining) :into result
:finally (return result)))
which results in:
> (group-iter '(a b c d e f) '(2 2 2))
(((A B) (F E D C)) ((A C) (F E D B)) ((A D) (F E C B)) ((A E) (F D C B))
((A F) (E D C B)) ((B C) (F E D A)) ((B D) (F E C A)) ((B E) (F D C A))
((B F) (E D C A)) ((C D) (F E B A)) ((C E) (F D B A)) ((C F) (E D B A))
((D E) (F C B A)) ((D F) (E C B A)) ((E F) (D C B A)))
But now I am totally failing to implement the nesting which takes care of the further processing of remaining. As far as I understood there is always a way to express a recursion with a iteration but how does it look like here?