in reply to A reproducible shuffle? ("stable shuffle")

I don't think that reseeding is ugly, since you can encapsulate it in a sub:
use strict; use warnings; use List::Util qw(shuffle); sub my_shuffle { my $old_seed = rand(2**32); srand(1); my @shuffled = shuffle(@_); srand($old_seed); return @shuffled; } print my_shuffle(qw(a b c d e f g)), $/; print my_shuffle(qw(a b c d e f g)), $/; print my_shuffle(qw(a b c d e f g)), $/;

Actually I'm not sure if the reseeding is done correctly.

Another possibility is to take List::Util's shuffle, and replace calls to rand with your own pseudo-random number generator, that you can keep separate from rand.

Replies are listed 'Best First'.
Re^2: A reproducible shuffle? ("stable shuffle")
by AK108 (Friar) on Feb 04, 2008 at 17:40 UTC
    Reseeding doesn't need to be cryptographically perfect. srand(Time::HiRes::time() ^ $$ ^ $other_randomness) should be good enough. Also, I have access to /dev/random and /dev/urandom, though I am uncertain how random they are (shared webhost), and it might be a slow operation. ps aux or a similar command (as suggested by perldoc -f random) is useless on this particular webhost due to their implementation.

    This is for a game, though, so I may decide to implement a PRNG anyway. In that case, losing the random seed wouldn't matter.

      For a game the reseeding in my post is certainly enough.

      /dev/random usually contains really good random numbers, but reading it could block your scripts by seconds or even minutes if the machine is low on entropy.

      /dev/urandom is much faster, but contains less "real" entropy. So /dev/urandom or the last state from rand before setting the seed should be OK.