sub naive_shuffle {
my $n = my @p = @_;
for my $i ( 0..$n-1 ) {
my $j = int rand $n;
@p[ $i, $j ] = @p[ $j, $i ]; # swap
}
return @p;
}
####
# untested
sub naive_shuffle_rec {
my $i = shift;
my $n = my @p = @_;
my $j = int rand $n;
@p[ $i, $j ] = @p[ $j, $i ]; # swap
return ++$i < $n ? naive_shuffle_rec( $i, @p ) : @p;
}
##
##
sub naive_shuffle_traverse {
my $i = shift;
my $j = shift;
my $n = my @p = @_;
@p[ $i, $j ] = @p[ $j, $i ] if defined $j; # swap
if ( ++$i < $n ) {
for my $j (0..$n-1) {
naive_shuffle_traverse( $i, $j, $tally, @p );
}
}
else {
return;
}
}
##
##
naive_shuffle_traverse(-1, undef, 1..3);
##
##
sub naive_shuffle_count {
my $i = shift;
my $j = shift;
my $tally = shift;
my $n = my @p = @_;
@p[ $i, $j ] = @p[ $j, $i ] if $j > -1;
if ( ++$i < $n ) {
for my $j (0..$n-1) {
naive_shuffle_count( $i, $j, $tally, @p );
}
}
else {
$tally->{ "@p" }++;
return;
}
}
##
##
my %tally = ();
naive_shuffle_count( -1, undef, \%tally, 1..3 );
##
##
DB<2> x \%tally
0 HASH(0x82d7f94)
'1 2 3' => 4
'1 3 2' => 5
'2 1 3' => 5
'2 3 1' => 5
'3 1 2' => 4
'3 2 1' => 4
##
##
sub random_perm {
my $n = my @p = @_;
for ( my $i = $#p; $i > 0; --$i ) {
my $j = int rand( $i + 1 );
@p[ $i, $j ] = @p[ $j, $i ];
}
return @p;
}