# Re: removing an element from a sequence

• From: Marco Antoniotti <marcoxa@xxxxxxxxx>
• Date: Fri, 7 Mar 2008 04:02:56 -0800 (PST)

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; ...