As far as I can tell, the "correct" shuffle in that post is wrong, int(rand() * $i) is always smaller than $i, so it will never generate a permutation where an element stays at the same position.<p>It is obvious from the numbers, too: the loop goes from $length - 1 to 1, so it has $length - 1 iterations, in the first iteration there are $length - 1 possible values for $r, in the second $length - 2, and the last iteration will always swap elements 0 and 1, for a total of (N-1)! different paths through the program, which are clearly not sufficient to generate N! different permutations.<p>[Edit: I had an off-by-one in my calculations, too. I hope it is correct now.]<p>[Edit: Actually, there still is an error in the first sentence: the algoritm will never leave the current element in its place, so the only element that is guaranteed not to stay at the same position is the last one. Run this:<p><pre><code> for my $i (1..1000000) {
my @a = (1..10);
my @b = shuffle(@a);
if ($b[10] == 10) {
die "Criticism is wrong $i";
}
}
]</code></pre>