Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

This would seem like an easy problem, but I'm not finding it to be as easy as expected.
Briefly, I would like to take an array and shuffle its elements.
However, sort { int(rand(2))?1:-1 } doesn't do what I want, as the following program demonstrates:
for $r (0..5000) {
  @a=sort { int(rand(2))?1:-1 } (0..9); 
  ($g)=grep($a$_==4,(0..9)); 
  $h{$g}++;
}
for $r (0..9) {print "$r $h{$r}\n";}
As you can see if you run this, the element originally in the fifth position has a much larger chance of staying put or of moving only slightly than it should if the list were truly randomly shuffled.
One thought I've had would be to start with a list of indices and randomly pick one at a time, something like:
@b=(0..9); @a=();
while(@b) {$i=int(rand($#b+1)); push @a, splice(@b,$i,1);}
Unfortunately, this seems awfully slow.

Replies are listed 'Best First'.
Re: Randomly sorted array
by ZZamboni (Curate) on Apr 27, 2000 at 17:23 UTC
Re: Randomly sorted array
by snowcrash (Friar) on Apr 27, 2000 at 17:30 UTC
    this algorithm for shuffling arrays is called Fisher-Yates shuffling, i shamelessly pasted it from the Perl Cookbook :)
    sub shuffle { my $arr = shift; my $x; for ($x = @$arr; --$x; ) { my $y = int rand ($x+1); next if $x == $y; @$arr[$x,$y] = @$arr[$y,$x]; } } shuffle(\@array);
RE: Randomly sorted array
by lhoward (Vicar) on Apr 28, 2000 at 17:10 UTC
    You may want to check out the Algorithm::Numerical::Shuffle module. It is very easy to use

    use Algorithm::Numerical::Shuffle qw /shuffle/; @shuffled = shuffle (1, 2, 3, 4, 5, 6, 7);


    Les Howard
    www.lesandchris.com
    Author of Net::Syslog and Number::Spell