Here is a direct, iterative solution generating the possibilities in reverse lexicographical order (no modules, no waste).
use strict; use warnings; my $base = 1; # minimum of cards per hole sub first { my( $holes, $cards ) = @_; my @c = ($base) x $holes; $c[0] += $cards - $base * $holes; $c[0] >= $base or die "Not enough cards!\n"; return \@c; } sub next_comp { my $c = shift; my $i = 0; $i++ while $i < @$c and $c->[$i] == $base; $i >= @$c-1 and return; $c->[$i+1]++; $c->[0] = $c->[$i] - 1; $c->[$i] = $base if $i > 0; return $c; } @ARGV == 2 or die print "Usage: $0 holes cards\n"; my $c = first( @ARGV ); my $i = 0; print ++$i.": @$c\n"; print ++$i.": @$c\n" while $c = next_comp $c;
This also reminds me of Odometer pattern iterator (in C). (Updated.).
In reply to Re: Combinatorics problem. (Updated with more info.)
by hdb
in thread Combinatorics problem. (Updated with more info.)
by BrowserUk
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |