[ # 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"; }