# Given a list of M items and a number N, # generate all size-N subsets of M sub choose_n { my \$n = pop; # Base cases return [] if \$n == 0 or \$n > @_; return [@_] if \$n == @_; # otherwise.. my (\$first, @rest) = @_; # combine \$first with all N-1 combinations of @rest, # and generate all N-sized combinations of @rest my @include_combos = choose_n(@rest, \$n-1); my @exclude_combos = choose_n(@rest, \$n); return ( (map {[\$first, @\$_]} @include_combos) , @exclude_combos ); } ##```## sub iter_choose_n { my \$n = pop; # Base cases my \$once = 0; return sub {\$once++ ? () : []} if \$n == 0 or \$n > @_; my (\$first, @rest) = @_; return sub {\$once++ ? () : [\$first, @rest]} if \$n == @_; ##``````## # otherwise.. my \$include_iter = iter_choose_n(@rest, \$n-1); my \$exclude_iter = iter_choose_n(@rest, \$n); return sub { if (my \$set = \$include_iter->()) { return [\$first, @\$set]; } else { return \$exclude_iter->(); } } ##``````## # otherwise.. my \$include_iter = iter_choose_n(@rest, \$n-1); my \$exclude_iter; return sub { if (my \$set = \$include_iter->()) { return [\$first, @\$set]; } else { \$exclude_iter ||= iter_choose_n(@rest, \$n); return \$exclude_iter->(); } } } ##``````## # otherwise.. my \$include_iter = iter_choose_n(@rest, \$n-1); my \$exclude_iter; return sub { if (\$include_iter and my \$set = \$include_iter->()) { return [\$first, @\$set]; } else { if (\$include_iter) { undef \$include_iter; \$exclude_iter = iter_choose_n(@rest, \$n); } return \$exclude_iter->(); } } } ```