Re: removing an element from a sequence



On Mar 6, 8:03 pm, t...@xxxxxxxxxxxxx (Thomas A. Russ) wrote:
"An[z]elmus" <some...@xxxxxxxxxxxxx> writes:
I took the idea from an old post in this newsgroup and re-wrote the
function.

(defun my-random (from to)
  (+ from (random (- to from))))

;;" ... randomly permute a vector of length n by swapping the first
;;element of the vector with a random (possibly also the first)
;;element.  After this swap, the first element in the permutation is
;;fixed.  We next swap the second element of the vector with a random
;;element other than the first element.  And so on. ..."
;;
;;uses my-random

(defun scramble04 (seq)
  (let ((lim (length seq)))
    (do ((n 0 (1+ n)))
        ((>= n lim))
      (setf rnd (my-random n lim))
      (rotatef (elt seq n) (elt seq rnd)))
    seq))

Well, the only problem that I see with tthis code is that it globally
sets the value of RND.  You don't want to do that.  There are three ways
you can avoid that.  I'll give them in increasing order of code
modification, although I'll say I prefer the last one best.

;; 1.  Establish local binding for the variable RND in the LET

(defun scramble04 (seq)
   (let ((lim (length seq))
         rnd)
     (do ((n 0 (1+ n)))
         ((>= n lim))
       (setf rnd (my-random n lim))
       (rotatef (elt seq n) (elt seq rnd)))
     seq))

;; 2.  Let DO do the updating for you

(defun scramble04 (seq)
   (let ((lim (length seq)))
     (do ((n 0 (1+ n))
          (rnd (my-random n lim) (my-random n lim)))
         ((>= n lim))
       (rotatef (elt seq n) (elt seq rnd)))
     seq))

;; 3.  Don't bother with a variable at all,
;;     since it's only used once

(defun scramble04 (seq)
   (let ((lim (length seq)))
     (do ((n 0 (1+ n)))
         ((>= n lim))
       (rotatef (elt seq n) (elt seq (my-random n lim))))
     seq))

;; 4.  Use DOTIMES instead of DO,
;;      since you don't need all that power

(defun scramble04 (seq)
  (let ((lim (length seq)))
    (dotimes (n lim)
       (rotatef (elt seq n) (elt seq (my-random n lim))))
    seq))

... and to be consistent with Common Lisp lore and revered traditions

(defun scramble (seq &aux
(lim (lenght seq))
(result (copy-seq seq)))
(dotimes (n lim result)
(rotatef (elt result n) (elt result (my-random n lim))))

(defun nscramble (seq &aux (lim (length seq)))
(dotimes (n lim seq)
(rotatef (elt seq n) (elt seq (my-random n lim))))

Cheers
--
Marco

.



Relevant Pages

  • Re: Hopefully simple lock-free problem (C-arrays)
    ...     Definition local; ... Vector contains fixed-size array of pointers to data blocks. ... handler to handle inconsistent reads during vector resize. ... size_t seq = obj.seq; ...
    (comp.programming.threads)
  • Re: Reset Autonum field
    ...   Obj 1 ... Using the Autonum field I can esaily rearrange them. ... You can however use a SEQ field and a reset ...
    (microsoft.public.word.docmanagement)
  • Re: Sequence splitting
    ...     if func is None: ... I fixed my version to take a bool default. ... t = filter(func, seq) ... is it ok to return lists? ...
    (comp.lang.python)
  • Re: Evolvers - sparse instruction set
    ... equivilant instructions like DAT.F and DAT.I. ...  Also CMP and SEQ. ... JMZ.F   JMZ.A   JMZ.B ... may be these are all the uniques out of the hundreds: ...
    (rec.games.corewar)
  • Re: A way to re-organize a list
    ... beginner wrote: ... and then by the first element. ... I found this handy class: ... for value in seq: ...
    (comp.lang.python)