# randomly permutate @array in place
my $array = shift;
my $i = @$array;
while ( --$i )
my $j = int rand( $i+1 );
@$array[$i,$j] = @$array[$j,$i];
fisher_yates_shuffle( \@array ); # permutes @array in place
And mentioned numerous times in numerous places, the 'next if $i == $j' is unnecessary, as it rarely saves an element swap (except on the smallest of arrays), so it actually costs more to do the comparison every time rather than just swapping unconditionally.
BTW, in case anyone was wondering who these guys Fisher and Yates were, here's some links. They're hard to find when almost every reference to Fisher and Yates (and especially with the term 'shuffle') on Google is a perl reference :-)
This "shuffles" the array, but not in a fair way. In fact,
the algorithm contains two mistakes, a minor one and a severe
one. Let's start with the minor one - in your loop you set
$rand to rand $#array. But that
means $rand could never be the last element of
the array. However, fixing it that you take rand @array
will not do you any good.
Let the size of the array be N. Then at each iteration,
you select from N elements (after the fix given above),
and change it with the one on position $i. You do this
N times. Hence, you will get NN
different outcomes. There are however, only N! different
permutations of the array. And since N! isn't a divisor of
NN for N > 2, some outcomes will be favoured over
others by your algorithm.
Please use the Fisher-Yates shuffle as described in the FAQ.
That one is fair.