Find The Wordiest Combination Lock
1275 words by simple greedy hill-climbing

Code is C#. Solution produced is

Score 1275 from ^[bcdfgmpstw][aehiloprtu][aeilnorstu][acdeklnrst][adehklrsty]$


I'm using that output format because it's really easy to test:

grep -iE "^[bcdfgmpstw][aehiloprtu][aeilnorstu][acdeklnrst][adehklrsty]$" linuxwords.txt | wc




namespace Sandbox {
    class Launcher {
        public static void Main(string[] args)
        {
            string[] lines = _Read5s();
            int[][] asMasks = lines.Select(line =&gt; line.ToCharArray().Select(ch =&gt; 1 &lt;&lt; (ch - 'a')).ToArray()).ToArray();
            Console.WriteLine(string.Format("{0} words found", lines.Length));

            // Don't even bother starting with a good mapping.
            int[] combos = _AllCombinations().ToArray();
            int[] best = new int[]{0x3ff, 0x3ff, 0x3ff, 0x3ff, 0x3ff};
            int bestSc = 0;
            while (true)
            {
                Console.WriteLine(string.Format("Score {0} from {1}", bestSc, _DialsToString(best)));

                int[] prevBest = best;
                int prevBestSc = bestSc;

                // Greedy hill-climbing approach
                for (int off = 0; off &lt; 5; off++)
                {
                    int[] dials = (int[])prevBest.Clone();

                    dials[off] = (1 &lt;&lt; 26) - 1;
                    int[][] filtered = asMasks.Where(mask =&gt; _Permitted(dials, mask)).ToArray();
                    int sc;
                    dials[off] = _TopTen(filtered, off, out sc);
                    if (sc &gt; bestSc)
                    {
                        best = (int[])dials.Clone();
                        bestSc = sc;
                    }
                }

                if (bestSc == prevBestSc) break;
            }

            Console.WriteLine("Done");
            Console.ReadKey();
        }

        private static int _TopTen(int[][] masks, int off, out int sc)
        {
            IDictionary&lt;int, int&gt; scores = new Dictionary&lt;int, int&gt;();
            for (int k = 0; k &lt; 26; k++) scores[1 &lt;&lt; k] = 0;

            foreach (int[] mask in masks) scores[mask[off]]++;

            int rv = 0;
            sc = 0;
            foreach (KeyValuePair&lt;int, int&gt; kvp in scores.OrderByDescending(kvp =&gt; kvp.Value).Take(10))
            {
                rv |= kvp.Key;
                sc += kvp.Value;
            }
            return rv;
        }

        private static string _DialsToString(int[] dials)
        {
            StringBuilder sb = new StringBuilder("^");
            foreach (int dial in dials)
            {
                sb.Append('[');
                for (int i = 0; i &lt; 26; i++)
                {
                    if ((dial &amp; (1 &lt;&lt; i)) != 0) sb.Append((char)('a' + i));
                }
                sb.Append(']');
            }
            sb.Append('$');
            return sb.ToString();
        }

        private static IEnumerable&lt;int&gt; _AllCombinations()
        {
            // \binom{26}{10}
            int set = (1 &lt;&lt; 10) - 1;
            int limit = (1 &lt;&lt; 26);
            while (set &lt; limit)
            {
                yield return set;

                // Gosper's hack:
                int c = set &amp; -set;
                int r = set + c;
                set = (((r ^ set) &gt;&gt; 2) / c) | r;
            }
        }

        private static bool _Permitted(int[] dials, int[] mask)
        {
            for (int i = 0; i &lt; dials.Length; i++)
            {
                if ((dials[i] &amp; mask[i]) == 0) return false;
            }
            return true;
        }

        private static string[] _Read5s()
        {
            System.Text.RegularExpressions.Regex word5 = new System.Text.RegularExpressions.Regex("^[a-z][a-z][a-z][a-z][a-z]$", System.Text.RegularExpressions.RegexOptions.Compiled);
            return File.ReadAllLines(@"d:\tmp\linuxwords.txt").Select(line =&gt; line.ToLowerInvariant()).Where(line =&gt; word5.IsMatch(line)).ToArray();
        }
    }
}