McA,
My brain is mush so unfortunately, this critique is just the things that jumped out at me.
%alphabet = (%alphabet, map { $_ => 1 } @chars);
Would be better written as:
@alphabet{@chars} = (); # No need to set values to 1 as you only ever
+use keys
I am not sure why you avoid autovivication but
if(defined $sorted{$characters}) {
push @{$sorted{$characters}}, $line;
}
else {
$sorted{$characters} = [$line];
}
Would work just as well as:
push @{$sorted{$characters}}, $line;
You waste a lot of time going through loops that you abort early
foreach (my $pos2 = 0; $pos2 < $count; $pos2++) {
next if $pos2 < $pos1;
Would work a lot more efficiently as:
for (my $pos2 = $pos1; $pos2 < $count; $pos2++) {
I haven't tested it but the way you determine if one is a subset of the other would probably be better as subtracting one hash from another.