http://qs321.pair.com?node_id=377887

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

I have a list of array elemetns and am trying to generate a sequential list of these elements. What would be the best way to do this?

Example:

my @array = (0..9); my $start = 4; my $end = 6;
Output would need to look like:

0000 1000 1100 1010 1001 2000 2100 2010 2001 3000 3100 3010 3001 4000 .... ..... ...... ...... 999999
Is there an easy or more efficient way of doing this? I want to have the generating start at the number of digits designated by $start and end when it gets to the number of digits designated by $end.

Replies are listed 'Best First'.
Re: Generate sequential array element combos
by BrowserUk (Patriarch) on Jul 27, 2004 at 23:45 UTC

    That is a very strange "sequential list". Maybe you could explain how 0000 is followed by 1000 followed by 1100?


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    "Memory, processor, disk in that order on the hardware side. Algorithm, algoritm, algorithm on the code side." - tachyon
Re: Generate sequential array element combos
by davidj (Priest) on Jul 28, 2004 at 01:17 UTC
    And not only what BrowserUk says, but you might also want to explain what
    my @array = (0..9); my $start = 4; my $end = 6;
    has to do with it.

    davidj
      It LOOkS like, he wants to do all permutations ('cept backwards from my example) using 4 characters to 6. The counting scheme seems such that
      0000 0001 0011 0101 1001 0002 0012 0102 1002 0009 0019 0109 1009 0029 0209 2009

      Bart: God, Schmod. I want my monkey-man.

        I'm with you up to '1009', but after that it's guess work. The only clue we have is that the final number is all nines. That suggests something like what you present, but it could just as well jump from '9001' (using his digit order) to 00000, the first five digit entry.

        Insufficent data.

        "Even if you are on the right track, you'll get run over if you just sit there." - Will Rogers
        Yeah I guess that is kinda weird list I gave.

        You are right though. I want to step through every possible combination given the integers 0 through 9 from 4 to 6 digits long. I guess a better list would be:

        0000
        0001
        0002
        0003
        0004
        0005
        0006
        0007
        0008
        0009
        0010
        0011
        0012
        ....
        ....
        9999 # Once the script maxes each place digit at 9
        00000 # it adds another place digit and starts over.
        00001
        .....
        .....
        99999 # Same here when all 5 digits are maxed at 9 it
        000000 # adds a 6th digit and starts over.
        000001
        ......
        ......
        999999
        Hope that makes more since.
Re: Generate sequential array element combos
by kelan (Deacon) on Jul 29, 2004 at 15:31 UTC

    Here's a clever, yet impractical, solution. It combines the eye-popping memory growth of tye's first solution, with the incomprensibility of string building.

    Anyway, glob() can do this pretty handily, the problem is you need to build the string it uses first:

    use strict; use warnings; # setup bounds my @digits = ( 0 .. 9 ); my $min_digits = 4; my $max_digits = 6; # build the glob string my $glob_string; for my $dignum ( 1 .. $max_digits ) { if ( $dignum <= $max_digits - $min_digits ) { $glob_string .= '{' . join( ',', ( '', @digits ) ) . '}'; } else { $glob_string .= '{' . join( ',', @digits ) . '}'; } } # print the permutations my $num; while ( $num = glob( $glob_string ) ) { print $num, "\n"; }
    $glob_string ends up looking like (split into two lines for better wrapping):
    {,0,1,2,3,4,5,6,7,8,9}{,0,1,2,3,4,5,6,7,8,9}{0,1,2,3,4,5,6,7,8,9}
    {0,1,2,3,4,5,6,7,8,9}{0,1,2,3,4,5,6,7,8,9}{0,1,2,3,4,5,6,7,8,9}
    
    which glob uses to do the work.

    I'll note that I was surprised by the memory consumption because in scalar context, glob is a simple iterator. But I suppose it builds all the matches up first and then iterates through them, instead of building them as it goes.