use strict; use warnings; my $string = "ATATGCGCAT"; my %levels = ( A => 3, T => 2, G => 2, C => 1, ); my @letters = split(//,$string); my $max = $#letters; my @numbers = map { 1 } @letters; while(1) { # Print the current combination of letters and numbers print "~"; for my $n (0..$max) { print $letters[$n] . $numbers[$n]; } print "~\n"; # Calculate the next set of numbers my $n = 0; $numbers[$n]++; while($numbers[$n] > $levels{$letters[$n]}) { $numbers[$n] = 1; $n++; last if($n > $max); $numbers[$n]++; } last if($n > $max); }