#-(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 <db19606@gmail.com>
;; 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: <ymifwtq4k6y.fsf@blackcat.isi.edu>
;;
;; 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 <vermilionrush@gmail.com>
;; 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 <kentilton@gmail.com>
;; 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 <pc@p-cos.net>
;; 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/
ViewGit