[
# First loop: all item indices
[ 0..$#items ],
# @items-1 subsequent loops:
( sub {
# If we need more items:
$sum[@_] < $target
# then get more (unique) item indices
? [ ($_+1)..$#items ]
# else don't get more items
: []
} ) x $#items,
],
####
for $_ ( 0..$#items ) {
# ...
for $_ ( @{ $sum[@_] < $target
? [ ($_+1)..$#items ] : [] }
) {
# ...
for $_ ( @{ $sum[@_] < $target
? [ ($_+1)..$#items ] : [] }
) {
# ...
}
}
}
##
##
OnlyWhen => sub {
# Compute sum of selected items as
# sum of @_-1 items plus last item:
$sum[@_]= $sum[$#_] + $items[$_[-1]];
# Return subsets that match desired sum:
return $sum[@_] == $target;
},
##
##
@_= ();
for $_ ( 0..$#items ) {
push @_, $_;
push @return, [ @_ ] if when( @_ );
for $_ ( @{ $sum[1] < $target
? [ ($_+1)..$#items ] : [] }
) {
push @_, $_;
push @return, [ @_ ] if when( @_ );
for $_ ( @{ $sum[2] < $target
? [ ($_+1)..$#items ] : [] }
) {
push @_, $_;
push @return, [ @_ ] if when( @_ );
# ...
pop @_;
}
pop @_;
}
pop @_;
}
##
##
$sum[@_] < $target ? [ ($_+1)..$#items ] : []
##
##
next if $target <= $sum[@_];
##
##
@_= ();
for $_ ( 0..$#items ) {
push @_, $_;
push @return, [ @_ ] if when( @_ );
next if $target <= $sum[1];
for $_ ( ($_+1)..$#items ) {
push @_, $_;
push @return, [ @_ ] if when( @_ );
next if $target <= $sum[2];
for $_ ( ($_+1)..$#items ) {
push @_, $_;
push @return, [ @_ ] if when( @_ );
# ...
} continue {
pop @_;
}
} continue {
pop @_;
}
} continue {
pop @_;
}
##
##
while( my @list= @items[ $iter->() ] ) {
warn "$target = sum( @list )\n";
}