sub nextPermute(\@) { my( $vals )= @_; my $last= $#{$vals}; return "" if $last < 1; # Find last item not in reverse-sorted order: my $i= $last-1; $i-- until $i < 0 || $vals->[$i] lt $vals->[$i+1]; # If complete reverse sort, we are done! return "" if -1 == $i; # Re-sort the reversely-sorted tail of the list: @{$vals}[$i+1..$last]= reverse @{$vals}[$i+1..$last] if $vals->[$i+1] gt $vals->[$last]; # Find next item that will make us "greater": my $j= $i+1; $j++ until $vals->[$i] lt $vals->[$j]; # Swap: @{$vals}[$i,$j]= @{$vals}[$j,$i]; return 1; } #Code to make the sample use below friendly: if( 0 == @ARGV ) { die "Usage: $0 word\n", " or: $0 t o k e n s\n", "Prints all unique permutations of the letters or words given.\n"; } elsif( 1 == @ARGV ) { @ARGV= $ARGV[0] =~ /(.)/gs; $"= ""; } #Sample use: @ARGV= sort @ARGV; do { print "@ARGV\n"; } while( nextPermute(@ARGV) );