Mailing List Archive: 49091 messages

[REBOL] Re: Question and comment about randomizing a block of values

From: joel:neely:fedex at: 18-Jun-2001 17:44

```
Hi, Jos (and all),

Sorry to be replying to my own post, but another bit of explanation
might be in order...

Joel Neely wrote:
>     random-iota: func [n [integer!] /local m f c r] [
>         f: n + 1
>         m: f * f
>         c: 0
>         r: make block! n
>         loop n [append r (f * random m) + c: c + 1]
>     ]
>

The reason why F needs to be N + 1 is that REBOL uses 1-origin
indexing instead of 0-origin indexing.  Since our weird numbers
have to have remainders in the range 1..N we have to multiply
the high-order randomness by N + 1 to protect all of the indexes.

The reason why M is F * F is simply to give RANDOM more of a
chance to "spread" the high-order randomness out, reducing the
probability that we'll get duplicates in the H-O R.

HOWEVER...

Upon further reflection, I've decided that the coupling between
RANDOM-IOTA and SHUFFLED is just too ugly for words.  Therefore,
I propose to atone for that ugliness that by offering the
slightly-less-ugly:

shuffled-iota: func [n [integer!] /local m f c r] [
m: n * n
c: -1
r: make block! n
loop n [append r (n * random m) + c: c + 1]
sort r
forall r [change r r/1 // n + 1]
]

shuffled-block: func [b [block!] /local n i r] [
r: make block! n: length? b
i: shuffled-iota n
foreach n i [append r pick b n]
]

which push all the arithmetic nastiness into SHUFFLED-IOTA,
and still behave as follows:

>> test-data: iota 20
== [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20]
>> new-data: shuffled-block test-data
== [16 8 11 20 5 2 19 10 18 1 17 15 7 4 13 12 9 3 14 6]
>> sort copy new-data
== [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20]

Cleaner is better!

-jn-
___     ___                                                   ___
\/ 2  + \/ 2  =  4  (for sufficiently large approximations of \/ 2 )

joel'dot'neely'at'fedex'dot'com
```