Using some slightly simplified code ripped from a future version of Algorithm::Loops I solved it like this (using an iterator so no worries about memory exhaustion for moderately large inputs):

my @input = ( 'a' .. 'e' ); my $max_subset = 3; my $iter = NestedLoops( [ sub { [0] }, ( sub { [ 0 .. 1+$_ ] } ) x $#input ], sub { return -1 if $max_subset < $_; return 1 if @_ == @input; }, ); my @slots; while( @slots = $iter->() ) { my @subsets = ('') x @input; $subsets[$slots[$_]] .= $input[$_] for 0 .. $#input; print "@subsets\n"; }

Producing this output:

abc de abc d e abd ce abe cd ab cde ab cd e abe c d ab ce d ab c de ab c d e acd be ace bd ac bde ac bd e ade bc ad bce ae bcd a bcd e ae bc d a bce d a bc de a bc d e ade b c ad be c ae bd c a bde c a bd ce ae b cd a be cd a b cde a b cd e ae b c d a be c d a b ce d a b c de a b c d e

Here is the simplified NestedLoops() I used:

sub NestedLoops { my( $loops, $when )= @_; my @list; my $i= -1; my @idx; my @vals= @$loops; my %freq; return sub { return } if ! @vals; return sub { while( 1 ) { # Prepare to append one more value: if( $i < $#$loops ) { $idx[++$i]= -1; local( $_ )= $list[-1]; $vals[$i]= $loops->[$i]->( @list ); } ## return if $i < 0; my $act = -1; while( $act < 0 ) { # Increment furthest value, chopping if done there: while( @{$vals[$i]} <= ++$idx[$i] ) { --$freq{ $list[$i] }; pop @list; return if --$i < 0; } $act = do { --$freq{ $list[$i] } if 0 < $idx[$i]; local $_ = ++$freq{ $list[$i]= $vals[$i][$idx[$i]] + }; $when->( @list ); }; return @list if 0 < $act; } } }; }

- tye        


In reply to Re: Combinatorics of Math::Combinatorics (Loops) by tye
in thread Combinatorics of Math::Combinatorics by watashi

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



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.