Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

While variations_with_repetition and mapm can reproduce the behaviour of the OP's original code, I wonder if his actual intent was precisely that.

Note that including the empty string in the list of "characters" adds shorter words to the output, while also introducing repetition and breaking lexicographic order. Each 5-letter word will appear 6 times, each 4-letter word 15 times, each 3-letter word 20 times, each 2-letter word 15 times, each single-letter word 6 times, and an empty line will also be in the output. Repeated strings will comprise 8.89 percent out of a total of 24,794,911,296 lines of output.

Let us assume that we wanted to generate all distinct non-empty strings with a given maximum length that can be build from a given alphabet.

The OP's approach with nested loops is in fact suitable for this task, with a little bit of modification.
#!/usr/bin/perl use strict; use warnings; my @alphabet = ('a'..'z', 'A'..'Z', '_'); foreach my $ch1 (@alphabet) { print $ch1, "\n"; foreach my $ch2 (@alphabet) { print $ch1, $ch2, "\n"; foreach my $ch3 (@alphabet) { print $ch1, $ch2, $ch3, "\n"; foreach my $ch4 (@alphabet) { print $ch1, $ch2, $ch3, $ch4, "\n"; foreach my $ch5 (@alphabet) { print $ch1, $ch2, $ch3, $ch4, $ch5, "\n"; foreach my $ch6 (@alphabet) { print $ch1, $ch2, $ch3, $ch4, $ch5, $ch6, "\n" +; } } } } } }

The variable @alphabet defines the characters available and their order. It does not contain an empty string. If we wanted another minimum word length we could simply remove the print statements in some of the outer loops.

The downside of this approach is that the word lengths are not controlled by simple parameters and that the code gets more and more repetitive with greater lengths.

A possible solution would be to put all those loop variables in an array and simulate how the nested loops iterate through those variables with a single loop, though at the price of a more complicated increment part, like this:

#!/usr/bin/perl use strict; use warnings; my @alphabet = ('a'..'z', 'A'..'Z', '_'); my $min_size = 1; my $max_size = 6; my @state = (); do { print @alphabet[@state], "\n" if $min_size <= @state; if (@state < $max_size) { push @state, 0; } else { for (my $i = $#state; $i >= 0; --$i) { last if ++$state[$i] < @alphabet; pop @state; } } } while (@state);

I recommend using a much smaller alphabet to test this. Note that I chose to use integer numbers in the @state array serving both as counters and indexes into the alphabet. The characters to print are then taken from an array slice.

While the second algorithm is certainly not easier to understand than the first, if a little bit shorter, it is much more flexible and still memory-efficient.

For a deeper understanding of combinatorial algorithms I warmly recommend the modern classic work by Donald E. Knuth, and its upcoming sequel.


In reply to Re: Is there a way more easy? by martin
in thread Is there a way more easy? by spadacciniweb

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (5)
As of 2024-04-18 05:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found