Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: shuffle array



2019-12-02 15:29:17 +0100, Roman Perepelitsa:
> Another alternative is to implement the standard inplace shuffle
> algorithm from scratch:
> 
>     local -i i
>     for ((i = 2; i <= $#l; ++i)); do
>       local j=$((RANDOM % i + 1))

shouldn't that be "RANDOM % $#l + 1"?

>       # swap l[i] and l[j]
>       local tmp=$l[i]
>       l[i]=$l[j]
>       l[j]=$tmp
>     done
> 
> Due to RANDOM having a rather narrow range, this will introduce bias
> on large arrays and won't work at all on arrays with more than 32k
> elements. These issues can be mitigated by replacing RANDOM with
> (RANDOM << 15 | RANDOM) or even with (RANDOM << 30 | RANDOM << 15 |
> RANDOM).
[...]

Or use rand48() in zsh/mathfunc

((j = 1 + rand48() * $#l))

-- 
Stephane



Messages sorted by: Reverse Date, Date, Thread, Author