Random number generation in LISP or using it

17 views
Skip to first unread message

bolega

unread,
Jun 10, 2009, 11:21:39 AM6/10/09
to
I am a newbie with the following problem.

A the outset let me state that the limitation is that I have to use
this inside emacs to scramble a set of chosen lines like you do
"reverse-region" or "sort-lines". It is possible that I can call some
scheme or clisp functions.

What is a fast(est) method to randomize lines based on the
capabilities of emacs ?

The function "random" does not work in emacs. I guess one get the
start line and end line of a marked region and then use that to
disorder (or re-order) the lines according to a list of random numbers
generated ?

1 -> 5
2 -> 8
3 -> 6
4 -> 9
5 -> 1
6 -> 3
7 -> 2
8 -> 7
9 -> 4

and then use these pairs to reorder the lines. I guess there is a need
for one or two variables to hold the lines, or just a kill or the top
line and go down a certain number of random steps and paste it there ?
Then come back to the top and do the same thing. The type of capacity
I am looking is to randomize about few hundred short lines of about 20
to 30 characters.

In this case one needs to generate a random number that is an integer
and lies between the lines start and end of region. It can be done by
some modulo type operation if available in emacs lisp.

Thanks for any help.
gnuist

bolega

unread,
Jun 10, 2009, 11:26:53 AM6/10/09
to
These are operations available via help in emacs but I dont know how
to use cl type operations in lisp defun.


*random-state*'s value is
[cl-random-state-tag -1 30 98807703]
Documentation:
not documented as a variable.
Defined in `cl'.


5x5-crack-randomly is an interactive autoloaded Lisp function in
`5x5'.
[Arg list not available until function definition is loaded.]
Attempt to crack 5x5 using random solutions.


cl-random-time is a compiled Lisp function in `cl'.
(cl-random-time)
not documented


make-random-state is an autoloaded Lisp function in `cl-extra'.
[Arg list not available until function definition is loaded.]
not documented


random is a built-in function.
(random &optional N)
Return a pseudo-random number.
All integers representable in Lisp are equally likely.
On most systems, this is 28 bits' worth.
With positive integer argument N, return random number in interval
[0,N).
With argument t, set the random number seed from the current time and
pid.

Colin S. Miller

unread,
Jun 10, 2009, 2:04:31 PM6/10/09
to
bolega wrote:
> I am a newbie with the following problem.
>
<snip>

>
> The function "random" does not work in emacs. I guess one get the
> start line and end line of a marked region and then use that to
> disorder (or re-order) the lines according to a list of random numbers
> generated ?

Bolega,
(random) is in the package cl. Since (random) doesn't have an autoload,
you'll need to use
(require 'cl)
before you can use (random).

<snip>

HTH,
Colin S. Miller

Lennart Borgman

unread,
Jun 10, 2009, 2:56:01 PM6/10/09
to Colin S. Miller, help-gn...@gnu.org

Or do as the manual says:

(eval-when-compile (require 'cl))

to avoid some potential problems.

Thomas A. Russ

unread,
Jun 10, 2009, 2:21:09 PM6/10/09
to
bolega <gnui...@gmail.com> writes:

> The function "random" does not work in emacs.

How does it not work?
It seems to work for me.

> start line and end line of a marked region and then use that to
> disorder (or re-order) the lines according to a list of random numbers
> generated ?

You could look up shuffling algorithms.


http://en.wikipedia.org/wiki/Shuffle#Shuffling_algorithms
http://en.wikipedia.org/wiki/Fisher-Yates_shuffle


[snip]

> In this case one needs to generate a random number that is an integer
> and lies between the lines start and end of region. It can be done by
> some modulo type operation if available in emacs lisp.

You shouldn't need to do that, since the built-in RANDOM function can do
that for you. Try ^H f random <CR>

--
Thomas A. Russ, USC/Information Sciences Institute

Thomas A. Russ

unread,
Jun 10, 2009, 2:21:40 PM6/10/09
to
bolega <gnui...@gmail.com> writes:

> The function "random" does not work in emacs.

How does it not work?


It seems to work for me.

> start line and end line of a marked region and then use that to


> disorder (or re-order) the lines according to a list of random numbers
> generated ?

You could look up shuffling algorithms.


http://en.wikipedia.org/wiki/Shuffle#Shuffling_algorithms
http://en.wikipedia.org/wiki/Fisher-Yates_shuffle


[snip]

> In this case one needs to generate a random number that is an integer


> and lies between the lines start and end of region. It can be done by
> some modulo type operation if available in emacs lisp.

You shouldn't need to do that, since the built-in RANDOM function can do

Xah Lee

unread,
Jun 10, 2009, 5:57:39 PM6/10/09
to
On Jun 10, 8:21 am, bolega <gnuist...@gmail.com> wrote:

your problem is very easily solved, in fact i have code you can mode a
bit to do exactly what you want.

The simplest solution, for your input size, is simply just to grab
your lines and save as list. Then, randomnize the list, then insert
them one by one. Probably a 20 min job.

i assume you know scheme or common lisp, just not familiar with emacs
lisp features.

To get your lines into list, as a example, see the grab-lines function
here:

• Elisp Lesson: Writing a google-earth Function
http://xahlee.org/emacs/google-earth.html

or you can see this page, that deals with reading lines one at a time.

• How To Process A File Line By Line In Elisp
http://xahlee.org/emacs/elisp_process_lines.html

basically, i'd just do this:

• move your cursor to beginning of first line. (Use search-backward on
\n\n.)
• Move your cursor to the beginning of first line. (move-beginning-of-
line)
• save cursor pos as pos1.
• move your cursor to end of line. move-end-of-line
• save cursor pos as pos2.
• use buffer-substring-no-properties to grab the line and push into a
list.
• Repeat above.
• Delete the lines in buffer if you haven't already.
• Once you have lines as a list, call random with list length as arg.
• remove that line from your list and insert into buffer.
• Repeat till you list has length 0.

Xah
http://xahlee.org/


TomSW

unread,
Jun 11, 2009, 3:34:12 AM6/11/09
to
On Jun 10, 5:21 pm, bolega <gnuist...@gmail.com> wrote:
> I am a newbie with the following problem.
>
> A the outset let me state that the limitation is that I have to use
> this inside emacs to scramble a set of chosen lines like you do
> "reverse-region" or "sort-lines". It is possible that I can call some
> scheme or clisp functions.

Grab the lines into an array, shuffle the array, re-insert the
lines :)

hth
Tom SW

------

(require 'cl) ; provides useful things like loop and setf

(defun shuffle-vector (vector)
"Destructively shuffle the contents of VECTOR and return it."
(loop
for pos from (1- (length vector)) downto 1
for swap = (random (1+ pos))
unless (= pos swap)
do (rotatef (aref vector pos)
(aref vector swap)))
vector)

(defun randomize-region (start end)
"Randomly re-order the lines in the region."
(interactive "r")
(save-excursion
(save-restriction
;; narrow to the region
(narrow-to-region start end)
(goto-char (point-min))
(let* ((nlines (line-number-at-pos end))
(lines (make-vector nlines nil)))
;;
(while (not (eobp))
(setf (aref lines (decf nlines)) ; if it's random backwards
is fine
(delete-and-extract-region (point)
(progn (forward-visible-
line 1)
(point)))))
;;
(let ((rlines (shuffle-vector lines)))
(dotimes (linenum (length rlines))
(insert (aref rlines linenum))))))))

Mario Lang

unread,
Jul 8, 2009, 7:54:27 AM7/8/09
to
bolega <gnui...@gmail.com> writes:

> What is a fast(est) method to randomize lines based on the
> capabilities of emacs ?

C-x h C-u M-| sort -R

--
CYa,
⡍⠁⠗⠊⠕

Pascal J. Bourguignon

unread,
Jul 8, 2009, 8:57:50 AM7/8/09
to
Mario Lang <ml...@delysid.org> writes:

This is not what was asked. sort -R puts together equal lines. AFAIK,
-R exists only in GNU sort, so it hasn't even the excuse of being
available everywhere emacs is available (see:
http://www.informatimago.com/linux/emacs-on-user-mode-linux.html
;-) )


(require 'cl) ; for coerce
(require 'cookie1) ; for shuffle-vector

(defun randomize-lines-of-region (start end)
(interactive "r")
(let* ((start (progn (goto-char start) (beginning-of-line) (point)))
(end (progn (goto-char end) (end-of-line) (point)))
(lines (shuffle-vector (coerce (split-string (buffer-substring start end) "\n") 'vector))))
(delete-region start end)
(insert (aref lines 0))
(dotimes (i (1- (length lines)))
(insert "\n" (aref lines (1+ i))))))


--
__Pascal Bourguignon__

Reply all
Reply to author
Forward
0 new messages