Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

How can I print all the numbers from 1 to n in random order?

by vroom (His Eminence)
on Jan 17, 2000 at 09:16 UTC ( [id://2127]=perlquestion: print w/replies, xml ) Need Help??

vroom has asked for the wisdom of the Perl Monks concerning the following question: (numbers)

How can I print all the numbers from 1 to n in random order?

Originally posted as a Categorized Question.

  • Comment on How can I print all the numbers from 1 to n in random order?

Replies are listed 'Best First'.
Re: How can I print all the numbers from 1 to n in random order?
by ChrisS (Monk) on Nov 14, 2003 at 17:36 UTC
    I'd use the List::Util module.
    use List::Util qw(shuffle); my $n = 10; # use $ARGV[0] or whatever to set $n print join " ", shuffle(1 .. $n);
Re: How can I print all the numbers from 1 to n in random order?
by btrott (Parson) on Apr 03, 2000 at 06:44 UTC
    I don't see the original here, so I don't know if this has been suggested... but you could just stick the numbers in an array, then shuffle the array, then print them. Use the Fisher-Yates Shuffle, which avoids the splice quadratic algorithm bit.
    sub fisher_yates_shuffle { my $array = shift; my $i; for ($i = @$array; --$i; ) { my $j = int rand ($i+1); next if $i == $j; @$array[$i,$j] = @$array[$j,$i]; } } my $N = 50; my @array = (1..$N); fisher_yates_shuffle( \@array ); # permutes @array in place print "@array";
    From perlfaq4, How do I shuffle an array randomly?.
Re: How can I print all the numbers from 1 to n in random order?
by lanval (Novice) on Apr 22, 2004 at 05:31 UTC
    $ cat numbers.pl
    #!/usr/bin/perl sub RandomiseArray { my (%b, $c); map { do { $c = rand } until(!exists $b{$c}); $b{$c} = $_ } @_ +; return values(%b); } my @a = RandomiseArray(1..10); print "@a\n";
    $ ./numbers.pl
    8 5 1 3 10 2 6 4 9 7
    $ ./numbers.pl
    4 2 3 9 5 8 6 1 7 10
    $ ./numbers.pl
    8 10 7 6 5 9 2 3 4 1


    Yeah?
      NO. (For an explanation, time it with RandomiseArray(1..1000) and RandomiseArray(1..100000) - it has exponential complexity in time)

      Here is a better way to do it:

      sub RandomiseArray { my @a=@_; my @b=(); while (scalar @a) { push(@b,splice(@a,int(rand @a))); } return(@b); }
      As the array becomes longer, the probablility of your routine finding an unused space becomes smaller and smaller. With a 1..10 shuffle the probablility of finding the right element for the last space is one in ten - which means you will need 10 tries (on the average). Not too bad. But with a 1..100000 array, you will need 100_000 tries to fill in the last element. and 99_999 to find the next to last, and... you get the idea. It will take a LOOONG time.

      Yeah, I could do it inplace (without the second copy of the array), but I'm going to save that for another time.

        The above comment would be true if it did $c = int(rand @_), but it doesn't. It just uses the floating point value returned from rand as a hash key. There are unlikely to be any collisions, even shuffling 1000000 numbers. You can test this with:
        perl -wle'undef $x{rand()} while keys(%x) == $x++; print $x'
        which adds keys until it gets a collision. Be prepared to wait a very long time.
Re: How can I print all the numbers from 1 to n in random order?
by chromatic (Archbishop) on Apr 02, 2000 at 06:28 UTC
    Hmm, see splice for why that doesn't work. Here's the fix: print (splice @a, rand @a, 1);

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://2127]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (3)
As of 2024-04-19 19:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found