my @typeset = qw(P K L G); my $length = 10; strangemultiset($length, \@typeset, 0, ''); sub strangemultiset { my ($len, $set, $start, $string) = @_; if ($len == 0) { print "$string\n"; return; } my $max = $len - @$set + $start + 1; my $min = $start == @$set - 1 ? $max : 1; for my $currentLen ($min..$max) { strangemultiset($len-$currentLen, $set, $start + 1, $string . ($set->[$start] x $currentLen)); } }