Here is one way. After reading your spec a couple of times, I think this is what you are looking for.
It is worth noting that it is possible that there will be more than one word with an equal upper score. There is only one winner from your list, but it is possible that a longer list will have several equally winning words. This decision concerns this. In addition, as I understand it, you consider letters to match only if they occur in the same column per word. If so, then here is a working solution:
use 5.012; use strict; use warnings; use List::Util 'max'; my @words = qw/ BAKER SALER BALER CARER RUFFR /; my @scores; foreach my $word ( @words ) { my $score; foreach my $comp_word ( @words ) { next if $comp_word eq $word; foreach my $pos ( 0 .. ( length $word ) - 1 ) { $score++ if substr( $word, $pos, 1 ) eq substr( $comp_word, $pos, 1); } } push @scores, $score; } my $max = max( @scores ); my ( @max_ixs ) = grep { $scores[$_] == $max } 0 .. $#scores; say "Words with most matches:"; say for @words[@max_ixs];
This decision counts how many times for each column of letters each word matches other words. For example:
Words: Scores: Because: ABC 1, 2, 1 = 4 A matched once, B matched twice, C matched once. ABD 1, 2, 1 = 4 A matched once, B matched twice, D matched once. CBD 0, 2, 1 = 3 C never matched, B matched twice, D matched once. BAC 0, 0, 1 = 1 B never matched, A never matched, C matched once.
This gives you the winners of ABC and ABD, each with a score of four positional matches. That is, cumulative moments when one column is one, row one corresponds to column one row two, three and four, etc. For subsequent columns. It may be able to be optimized and reformulated to be shorter, but I tried to make the logic pretty easy to read. Enjoy it!
UPDATE / EDIT I thought about this and realized that although my existing method does exactly what your original question asked, it did it O (n ^ 2) times, which is relatively slow. But if we use hash keys for each letter of the column (one letter per key) and count how many times each letter appears in the column (as the value of the hash element), we could do our sums in O (1) and our traversal of the list in O (n * c) time (where c is the number of columns, n is the number of words). There is also setup time (creating a hash). But we still have big improvements. Here is a new version of each technique, as well as a comparative comparison of each of them.
use strict; use warnings; use List::Util qw/ max sum /; use Benchmark qw/ cmpthese /; my @words = qw/ PARTNERSHIPS REPRIMANDING CIVILIZATION APPRECIATION CONVERSATION CIRCUMSTANCE PURIFICATION SECLUSIONIST CONSTRUCTION DISAPPEARING TRANSMISSION APPREHENSIVE ENCOUNTERING /;
Conclusion:
Testing force method: 39 matches. APPRECIATION Testing hash method: 39 matches. APPRECIATION Rate Force Hash Force 2358/s -- -74% Hash 9132/s 287% --
I understand that your initial specification changed after you saw some other options, and the nature of innovation to a certain extent, but the puzzle is still alive in my mind. As you can see, my hash method is 287% faster than the original method. More fun in less time!