use v5.14; use Sort::Key::Top 'nkeytopsort'; sub sort_letters { my @letters = split '', $_[0]; join '', sort @letters; } sub can_make { my ($letters, $word) = @_; $word = join '.*', sort split '', $word; $letters =~ qr{$word}; } say "Reading words from dictionary..."; open my $dict, '<', '/usr/share/dict/words'; chomp( my @WORDS = map lc, grep length($_) <= 9, <$dict> ); say "Scoring microcombinations..."; my %SCORE; $SCORE{ sort_letters($_) }++ for @WORDS; my @GOOD = nkeytopsort { $SCORE{$_} } -40 => keys %SCORE; say "Generating candidate answers..."; my %CANDIDATES; for my $x (@GOOD) { for my $y (@GOOD) { for my $z (@GOOD) { my $letters = sort_letters substr("$x$y$z", 0, 8); $CANDIDATES{$letters}++; } } } my @VERYGOOD = nkeytopsort { $SCORE{$_} } -40 => keys %CANDIDATES; say "Finding best candidate answer..."; my %RESULTS = map { my $letters = $_; my @can_make = grep can_make($letters, $_), @WORDS; say " $letters - ", scalar(@can_make); $letters => \@can_make; } @VERYGOOD; my ($BEST) = nkeytopsort { scalar @{$RESULTS{$_}} } -1 => @VERYGOOD; say "BEST: $BEST"; say for sort @{$RESULTS{$BEST}};