On 6/12/07, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote:
snip
I can see how to generate a random number between 0 and 6 (meaning I
can pick one of the 7 characters in my source string) by using "print
int(rand(6))",  but I don't know where to being on the second and
third and fourth characters to and check that the random number hasn't
already been chosen.
snip

What you are describing sounds like it would be best implemented by
1 breaking the the string into individual characters and storing them
in an array
2 shuffling the array
3 joining all but the last element of the array

Breaking a string into its characters in Perl is easy

my $str = "1234567";
my @a  = split //, $str;

Shuffling an array is easy as well.  Let's use Knuth's* shuffle
algorithm.  The idea here is to swap the current cell with some cell
that has not yet been processed.  So, the first cell can be swapped
with any other cell, the second cell can be swapped with any cell
other than the first, the third can swapped with any but the first and
second, and so on.  This will result in a shuffled array where any
permutation is equally likely**.

for my $i (0 .. $#a) {
   my $r = $i + int rand(@a - $i);
   @a[$i, $r] = @a[$r, $i];
}

Now that we have permuted the array we can turn a subset of it back
into a string and print it.

$str = join '', @a[0 .. $#a - 1];
print "$str\n";

And here it is put all together with a loop

#!/usr/bin/perl

use strict;
use warnings;

my $str = "ABCDEFG";
print "$str\n";

while (length($str) > 1) {
       my @a = split //, $str;
       for my $i (0 .. $#a) {
               my $r = $i + int rand(@a - $i);
               @a[$i, $r] = @a[$r, $i];
       }
       $str = join '', @a[0 .. $#a - 1];
       print "$str\n";
}

* also known as the Fisher-Yates shuffle
** given a sufficiently good RNG

--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/


Reply via email to