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

hi-

My research involves DNA sequences. I have a function that receives lists. Lists received are of arbitrary lengths and the number of lists received cannot be known a priori.

I would like to be able to produce all combinations of the lists' elements while preserving the order of the lists. An example follows:

Suppose we have 3 lists:

list 1: (1,2)

list 2: (a,b)

list 3: (#,*,&)

i would like to produce the following:

1,a,#

1,a,*

1,a,&

1,b,#

1,b,*

1,b,&

2,a,#

2,a,*

2,a,&

2,b,#

2,b,*

2,b,&

PS. I have solutions for the problem that would return the whole list of combinations. However, my combinations (of DNA sequences) tend to be in the thousands even millions and i'm running out of memory! I need a way that would return one combination at a time so i can operate on it, discard it, and get the second combination and so on without having to store the whole list of combinations in memory. I appreciate your help guys but could you please run any code you suggest. If i don't get your code, it's hard for me to fix it :( Thanks a lot

Replies are listed 'Best First'.
Re: permutations problem
by ikegami (Patriarch) on Sep 17, 2009 at 18:26 UTC
    Algorithm::Loops's NestedLoop is exactly what you need.
    use Algorithm::Loops qw( NestedLoops ); my @inputs = ( [qw( 1 2 )], [qw( a b )], [qw( $ * & )], ); my $iter = NestedLoops(\@inputs); while ( my @list = $iter->() ) { print(join(',', @list), "\n"); }

    It doesn't build the result set in advance. It uses minimal memory by only generating the next permutation when requested.

Re: permutations problem
by moritz (Cardinal) on Sep 17, 2009 at 18:27 UTC
    Set::CrossProduct was written specifically for this purpose.
    Perl 6 - links to (nearly) everything that is Perl 6.
Re: permutations problem
by Fletch (Bishop) on Sep 17, 2009 at 19:13 UTC

    And this is different than all binary combinations or the nigh-identical Combinatorics problem from two weeks ago that already gave you plenty to go on despite your not showing any effort there either?

    (Aside from wiseacres giving you Haskell code there rather than Perl, of course)

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

      FYI. It IS identical to the Combinatorics problem however, if you read what i wrote (apparently you didn't) the constraint is to generate each combination sequentially since the whole list (which previous solutions provide) is too big to fit in memory. It might help you understand if you took the 20 seconds to read rather than surrendering to the compulsive need to reply.
Re: permutations problem
by BrowserUk (Patriarch) on Sep 18, 2009 at 02:11 UTC

    If you like simple, try this:

    #! perl -slw use strict; sub nFor(&@) { my $code = shift; die "First argument must be a code ref" unless ref( $code ) eq 'CO +DE'; my @limits = @_; my @indices = ( 0 ) x @limits; for( my $i = $#limits; $i >= 0; ) { $i = $#limits; $code->( @indices ), ++$indices[ $i ] while $indices[ $i ] < $limits[ $i ]; $i = $#limits; $indices[ $i ] = 0, ++$indices[ --$i ] while $i >= 0 and $indices[ $i ] == $limits[ $i ]; } } my @list1 = ( 1, 2 ); my @list2 = qw[ a b ]; my @list3 = qw[ # * & ]; ## Your code goes in the block below ## The list is the number of elements in each array ## Each time the block is called ## $_[0] is the index to use in the first list ## $_[1] " ## $_[2] 8 ## etc. nFor { print join '', $list1[ $_[0] ], $list2[ $_[1] ], $list3[ $_[2] ]; } 2,2,3; __END__ C:\test>795953.pl Possible attempt to put comments in qw() list at C:\test\795953.pl lin +e 23. 1a# 1a* 1a& 1b# 1b* 1b& 2a# 2a* 2a& 2b# 2b* 2b&

    If your lists are arranged as a list of lists, things get a little tidier.

    Update:To clarify, if your lists are arranged as an AoAs, then the problem generalises to:

    my @lists = ( [ 1, 2 ], [ qw[ a b ] ], [ qw[ # * & ] ] ); nFor { print join '', map $lists[ $_ ][ $_[ $_ ] ], 0 .. $#_; } map scalar @$_, @lists;

    Which handles any number of lists or items transparently.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: permutations problem
by jdrago_999 (Hermit) on Sep 22, 2009 at 17:59 UTC
    How are you supposed to get any work done if you can't install some code???
A reply falls below the community's threshold of quality. You may see it by logging in.