#-(and) " P16 (**) Drop every N'th element from a list. Example: * (drop '(a b c d e f g h i k) 3) (A B D E G H K) " ;; From: Dan Becker ;; Subject: list looping ;; Newsgroups: comp.lang.lisp ;; Date: Tue, 21 Dec 2010 14:06:58 -0800 (PST) ;; Organization: http://groups.google.com ;; Message-ID: <9d846d29-3d63-4037-9410-86fdcabc8e93@i18g2000yqn.googlegroups.com> ;; ;; For exercise I'm running through the problems from here: ;; ;; http://www.ic.unicamp.br/~meidanis/courses/mc336/2006s2/funcional/L-99_Ninety-Nine_Lisp_Problems.html ;; ;; For some of these, I'm wanting to write code that loops through a list ;; in parallel with updating some other variable, so I end up with ;; functions like this: (defun drop (list n) "returns result of dropping every nth element of list" (do ((l list (cdr l)) (i 1 (1+ i)) (result nil)) ((null l) (nreverse result)) (unless (= (mod i n) 0) (push (car l) result)))) ;; I know there's also an approach using LOOP that I think I like better: (defun drop (list n) "returns result of dropping every nth element of list" (loop for elem in list for i from 1 unless (= (mod i n) 0) collect elem)) ;; From: tar@sevak.isi.edu (Thomas A. Russ) ;; Subject: Re: list looping ;; Newsgroups: comp.lang.lisp ;; Date: 21 Dec 2010 18:26:13 -0800 ;; Organization: USC Information Sciences Institute ;; Message-ID: ;; ;; Another choice that doesn't use MOD: (defun drop (list n) (let ((result nil)) (loop while list do (loop repeat (1- n) while list do (push (pop list) result)) (pop list)) (nreverse result))) ;; This would be cleaner if one knew that the list length was a multiple of ;; the drop count. ;; -- ;; Thomas A. Russ, USC/Information Sciences Institute ;; From: Ariel Badichi ;; Subject: Re: list looping ;; Newsgroups: comp.lang.lisp ;; Date: Wed, 22 Dec 2010 05:13:05 +0200 ;; Organization: A noiseless patient Spider ;; Message-ID: <87ei9ah54u.fsf@gmail.com> ;; ;; Here's a "cute" attempt: (defun drop (sequence n &aux (i 0)) "Remove every Nth element of SEQUENCE." (remove-if (lambda (item) (divisible-by-p (incf i) n)) sequence)) (defun divisible-by-p (m n) "Return true if M is divisible by N, and false otherwise." (zerop (mod m n))) ;; The issues with this DROP are that it (i) assumes REMOVE-IF calls the ;; predicate with elements in order, which I'm not sure is guaranteed by ;; the Standard (ii) has a side-effecting predicate (iii) does not declare ;; ITEM as ignored (iv) uses &AUX. ;; ;; Ariel ;; From: kenny ;; Subject: Re: list looping ;; Newsgroups: comp.lang.lisp ;; Date: Wed, 22 Dec 2010 02:34:41 -0800 (PST) ;; Organization: http://groups.google.com ;; Message-ID: <3ffa4a93-ed93-4eab-b36d-6ac69aa52fad@w17g2000yqh.googlegroups.com> ;; ;; Oh, we can get that with the loop version; (defun drop (list n) (loop :for elt :in list :for i :from 1 :for die-elt-die! = (zerop (mod i n)) :unless die-elt-die! :collect elt)) ;; out-out-damned-elt! would work as well. ;; ;; hth, ;; ;; kt ;; From: Pascal Costanza ;; Subject: Re: list looping ;; Newsgroups: comp.lang.lisp ;; Date: Wed, 22 Dec 2010 15:56:47 +0100 ;; Message-ID: <8nehtfFgrpU1@mid.individual.net> ;; ;; Here is my suggestion: (defun drop (list n &aux (m (1- n))) (loop :for a = list :then (cdr b) :for b = (nthcdr m a) :if b :nconc (ldiff a b) :else :nconc a :and :do (loop-finish))) ;; I tend to use &aux when I need a variable that is only a 'minor ;; variation' of one or more of the parameters (where 'minor' is a highly ;; subjective judgment). ;; ;; ;; Pascal ;; ;; -- ;; My website: http://p-cos.net ;; Common Lisp Document Repository: http://cdr.eurolisp.org ;; Closer to MOP & ContextL: http://common-lisp.net/project/closer/