use Math::Random::MT; my $mt = Math::Random::MT->new(); sub badRand($) { rand() < 0.5 ? 0 : rand( $_[0] ) } sub goodRand($) { rand($_[0]) } sub bestRand($) { $mt->rand($_[0]) } #### #!/usr/bin/env perl use strict; use Statistics::ChiSquare; use Math::Random::MT; my $mt = Math::Random::MT->new(); my $NUMTESTS = 100000; sub badRand($) { rand() < 0.5 ? 0 : rand( $_[0] ) } sub goodRand($) { rand($_[0]) } sub bestRand($) { $mt->rand($_[0]) } my %tests = ( 'bad_shuffle' => { 'randsub' => \&badRand, 'rands' => undef }, 'good_shuffle' => { 'randsub' => \&goodRand, 'rands' => undef }, 'best_shuffle' => { 'randsub' => \&bestRand, 'rands' => undef }, ); my @vals = ( 1..4 ); foreach (keys %tests){ my $asub = $tests{$_}->{'randsub'}; $tests{$_}{'results'} = do_a_shuffle($asub, @vals); $tests{$_}{'chi'} = Statistics::ChiSquare::chisquare(values %{$tests{$_}{'results'}}); print $_ . " : " . $tests{$_}{'chi'}."\n"; } # &randsub, @choices sub shuffle { my $randsub = shift; # rest of params are the values/choices to shuffle $a = $_ + $randsub->( @_ - $_ ), $b = $_[$_], $_[$_] = $_[$a], $_[$a] = $b for 0 .. $#_; return @_; } # &randsub, @choices sub do_a_shuffle { my %tests; for(1..$NUMTESTS){ ++$tests{ join '', shuffle(@_) }; } return \%tests; } __END__