sub iter { my @factors = @_; my $str; my $break = 0; return sub { if (not defined $str) { $str = "1" . ("0" x $#factors); return map { substr($str, $_, 1) ? $factors[$_] : () } 0 .. $#factors; } for ($str) { s/0(0*)$/1$1/ and last; return "BREAK" if $break = !$break; s/11$/01/ or s/^(.*)10(.*)$/"${1}01" . "0" x length $2/e or return; } return map { substr($str, $_, 1) ? $factors[$_] : () } 0 .. $#factors; }; } my $i = iter( 2, 3, 5, 7 ); while (my @s = $i->()) { print "@s\n"; } __END__ 2 2 3 2 3 5 2 3 5 7 BREAK 2 3 7 BREAK 2 5 2 5 7 BREAK 2 7 BREAK 3 3 5 3 5 7 BREAK 3 7 BREAK 5 5 7 BREAK 7 BREAK