$ time t.pl 2of12inf.txt Done processing dict (40933 words). Candidate counts, by number of letters: $VAR1 = [ 0, 53, 516, 1894, 4068, 7076, 10360, 11926 ]; Done computation. Result (most words at bottom): aabdellu : 1 emprrtuy : 1 [... output truncated ...] aeginrst : 296 aelmprst : 297 acelprst : 297 aceiprst : 303 adeimrst : 305 adeoprst : 307 aeimnrst : 307 aeilnpst : 308 adeinrst : 311 aeilnrst : 311 adeilrst : 319 aeimprst : 327 adeiprst : 331 aeinprst : 336 aeilprst : 343 real 0m4.860s user 0m3.665s sys 0m0.160s #### #!/usr/bin/perl use strict; use warnings; use List::Util qw(sum); use Data::Dumper; my $MAXLEN = 8; my @data; my $words_processed = 0; while (<>) { s/[%\s]+//g; my $len = length; next unless 1 <= $len && $len <= $MAXLEN; ++$words_processed; my @a = sort split //, lc; my $w = join "", @a; ++$data[$len - 1]{$w}{count}; $data[$len - 1]{$w}{contrib}{$w} = 1; $data[$len - 1]{$w}{alphas} ||= \@a; } print "Done processing dict ($words_processed words). Candidate counts, by number of letters:\n"; print Dumper [map { $_ ? scalar(keys %$_) : 0 } @data]; for my $c (1 .. $MAXLEN - 1) { my $data1 = $data[$c - 1]; my $data2 = $data[$c]; next unless $data1 && $data2; for my $v1 (values %$data1) { for my $extra ("a" .. "z") { my $new = join "", sort(@{ $v1->{alphas} }, $extra); if ($data2->{$new}) { $data2->{$new}{contrib}{$_} = 1 for keys %{ $v1->{contrib} }; } } } } my $data_max = $data[$MAXLEN - 1]; for my $v (values %$data_max) { $v->{total} = sum(map $data[length($_) - 1]{$_}{count}, keys %{ $v->{contrib} }); } print "\nDone computation. Result (most words at bottom):\n"; for my $w (sort { $data_max->{$a}{total} <=> $data_max->{$b}{total} } keys %$data_max) { print "$w : $data_max->{$w}{total}\n"; }