Gangabass has asked for the wisdom of the Perl Monks concerning the following question:

Hi, Monks.

Sorry if you discuss this question many time but search (and Super Search) did't help me so...

I need to generate all word from the pattern. The pattern looks like so: LLL (generate all free letter words), LLN (generate all words with two letters at beginig and digit at the end), LNNLLN.

Maybe there is a way to translate Perl regex pattern (like /[a-z]{3}/ or /[a-z]{2}\d/) to words list?

All i can invent is ugly nested for circles:

my @first_symbol_range = @second_symbol_range = ( 'a'..'z' ); my @fird_symbol_range = ( 0..9 ); for my $first_symbol (@first_symbol_range) { for my $second_symbol (@second_symbol_range) { for my $fird_symbol (@fird_symbol_range) { my $word = $first_symbol . $second_symbol . $fird_symbol; } } }

But i don't know length of the result string (it could be 10 symbols) :-(. So please show me the right way. Thanks!

Replies are listed 'Best First'.
Re: Words generation algorithm
by blokhead (Monsignor) on Nov 04, 2007 at 02:36 UTC
    A solution using tye's Algorithm::Loops:
    use Algorithm::Loops 'NestedLoops'; my %pat = ( L => ['a' .. 'z'], N => [0 .. 9] ); my $pattern = shift || "LLN"; NestedLoops( [ @pat{ split //, $pattern } ], sub { print join("", @_), $/ } );
    Or one using glob:
    my %pat = ( L => ['a' .. 'z'], N => [0 .. 9] ); my $pattern = shift || "LLN"; $_ = sprintf "{%s}", join ",", @$_ for values %pat; my $glob = join "", @pat{ split //, $pattern }; print "$_\n" for glob($glob);
    However, the glob version will generate all the expansions in memory (even if you use the iterator interface to glob). NestedLoops generates them as needed.

    BTW, if your pattern calls for all 10-character-long strings, you will have between 10 billion and 100,000 billion strings generated. I'm guessing you probably don't need them all. What do you really want to accomplish?

    blokhead

      It's work like the charm! Thanks!

Re: Words generation algorithm
by planetscape (Chancellor) on Nov 04, 2007 at 02:16 UTC
Re: Words generation algorithm
by hossman (Prior) on Nov 04, 2007 at 05:38 UTC

    I think the regex forms of your patterns are simple enough that Regexp::Genex will work for you ... but i haven't actually verified that.

      I'm mandatory look at this later. Thanks for idea!

Re: Words generation algorithm
by ikegami (Patriarch) on Nov 04, 2007 at 15:59 UTC
    Or you could use glob.
    my $pat = 'LLN'; my %pats = ( L => [ 'a'..'z' ], N => [ '0'..'9' ], ); ($_) = map "{$_}", join ',', @$_ for values %pats; (my $glob = $pat) =~ s/(.)/$pats{$1}/g; print("$_\n") for glob $glob;

    Update: I'm blind. I hadn't seen blokhead's glob solution (only his NestedLoops solution) before posting this.