Finden Sie das Wortreichste Zahlenschloss

18

Ich habe ein Kombinationsschloss mit Buchstaben anstelle von Zahlen. Es sieht so aus: http://pictures.picpedia.com/2012/09/Word_Combination_Padlock.jpg Es gibt 5 Walzen mit jeweils 10 verschiedenen Buchstaben.

Die meisten Leute verwenden lieber ein Wort für ihre Kombination als eine willkürliche Folge von Buchstaben. (Natürlich weniger sicher, aber leichter zu merken.) Bei der Herstellung des Schlosses ist es daher ratsam, eine Buchstabenkombination zu erstellen, mit der so viele englische Wörter wie möglich aus 5 Buchstaben erstellt werden können.

Ihre Aufgabe ist es, eine Zuordnung von Buchstaben zu Rollen zu finden, mit der so viele Wörter wie möglich erstellt werden können. Zum Beispiel könnte Ihre Lösung sein

ABCDEFGHIJ DEFGHIJKLM ZYXWVUTSR ABCDEFGHIJ ABCDEFGHIJ

(Wenn Sie sich nicht zu einfallsreich fühlten, ist das).

Verwenden Sie aus Gründen der Konsistenz die Wortliste unter http://www.cs.duke.edu/~ola/ap/linuxwords

Jedes 5-Buchstaben-Wort in dieser Liste ist in Ordnung, einschließlich Eigennamen. Ignorieren Sie Sino- und L'vov sowie alle anderen Wörter in der Liste, die ein Nicht-Az-Zeichen enthalten.

Das Gewinnerprogramm ist dasjenige, das die größte Menge an Wörtern produziert. Für den Fall, dass mehrere Programme dasselbe Ergebnis erzielen, gewinnt das erste Programm, das veröffentlicht wird. Das Programm sollte in weniger als 5 Minuten ausgeführt werden.

Edit: da die Aktivität nachgelassen hat und keine besseren Lösungen herausgekommen sind, erkläre ich Peter Taylor zum Gewinner! Vielen Dank an alle für Ihre einfallsreichen Lösungen.

Edwin Young
quelle
Wie kann man Eigennamen zählen, wenn man bedenkt, dass sie zwischen den Kulturen so unterschiedlich sind?
Elssar
@elssar, Wenn ich es richtig verstehe, ist jedes Wort in der Liste in Ordnung, unabhängig davon, ob es sich um einen richtigen Namen handelt (in einer beliebigen Kultur).
Ugoren
Oh richtig, die da
drin
Also keine Code-Frage; aber Logik?
Brigant
2
Dies ist als Code-Herausforderung gekennzeichnet : Was ist die Herausforderung? Alles, was Sie gefragt haben, ist der Wert, der eine Funktion maximiert, deren Domänengröße etwa 110,3 Bit beträgt. Es ist also nicht machbar, das Problem mit Gewalt zu lösen, aber es sollte machbar sein, die genaue Antwort zu erhalten und vielleicht sogar zu beweisen, dass es richtig ist. In Anbetracht dessen, was sind die Voraussetzungen für eine zu berücksichtigende Antwort und nach welchen Kriterien werden Sie einen Gewinner auswählen?
Peter Taylor

Antworten:

6

1275 Wörter durch einfaches gieriges Bergsteigen

Code ist C #. Lösung hergestellt wird

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

Ich verwende dieses Ausgabeformat, weil es sehr einfach zu testen ist:

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 => line.ToCharArray().Select(ch => 1 << (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 < 5; off++)
                {
                    int[] dials = (int[])prevBest.Clone();

                    dials[off] = (1 << 26) - 1;
                    int[][] filtered = asMasks.Where(mask => _Permitted(dials, mask)).ToArray();
                    int sc;
                    dials[off] = _TopTen(filtered, off, out sc);
                    if (sc > 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<int, int> scores = new Dictionary<int, int>();
            for (int k = 0; k < 26; k++) scores[1 << k] = 0;

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

            int rv = 0;
            sc = 0;
            foreach (KeyValuePair<int, int> kvp in scores.OrderByDescending(kvp => 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 < 26; i++)
                {
                    if ((dial & (1 << i)) != 0) sb.Append((char)('a' + i));
                }
                sb.Append(']');
            }
            sb.Append('$');
            return sb.ToString();
        }

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

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

        private static bool _Permitted(int[] dials, int[] mask)
        {
            for (int i = 0; i < dials.Length; i++)
            {
                if ((dials[i] & 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 => line.ToLowerInvariant()).Where(line => word5.IsMatch(line)).ToArray();
        }
    }
}
Peter Taylor
quelle
Ich wollte gerade meine Antwort mit dieser genauen Lösung bearbeiten, aber Sie haben mich geschlagen.
cardboard_box
Wenn ich die gleiche Bergsteigersuche aus 1000 zufälligen Startkombinationen durchführe und die besten der 1000 gefundenen lokalen Optima auswähle, scheint es immer die gleiche Lösung zu geben, sodass es wahrscheinlich das globale Optimum ist.
Peter Taylor
Das kommt auf deine Definition von wahrscheinlich an ;-) Aber es wird weiter durch andere Ansätze "bestätigt", die maximal 1275 ergeben. (Und wo ist der Quantum-Tic-Tac-Toe geblieben?)
Howard
@Howard, das war nur ein Artefakt von .Net, das nicht mehrere Einstiegspunkte in einem einzigen Projekt unterstützt. Ich habe ein "Sandbox" -Projekt, das ich für solche Dinge verwende, und ich ändere normalerweise die MainMethode, um verschiedene _MainMethoden aufzurufen .
Peter Taylor
Ich habe einen genetischen Algorithmus ausprobiert und in ein paar Minuten das gleiche Ergebnis erzielt, und in der nächsten Stunde nichts. Es würde mich also nicht wundern, wenn es das Optimum ist.
cardboard_box
4

Python (3), 1273 ≈ 30,5%

Dies ist ein wirklich naiver Ansatz: Halten Sie die Häufigkeit jedes Buchstabens an jeder Position fest und eliminieren Sie dann den "schlechtesten" Buchstaben, bis die verbleibenden Buchstaben auf die Rollen passen. Ich bin überrascht, dass es so gut zu laufen scheint.

Am interessantesten ist, dass ich fast genau die gleiche Ausgabe wie die C # 1275-Lösung habe, außer dass ich eine Nauf meiner letzten Rolle anstelle von habe A. Das Awar auch meine elfte bis letzte Eliminierung, noch bevor ich a Vund a weggeworfen habe G.

from collections import Counter

def main(fn, num_reels, letters_per_reel):
    # Read ye words
    words = []
    with open(fn) as f:
        for line in f:
            word = line.strip().upper()
            if len(word) == num_reels and word.isalpha():
                words.append(word)

    word_pool_size = len(words)

    # Populate a structure of freq[reel_number][letter] -> count
    freq = [Counter() for _ in range(num_reels)]
    for word in words:
        for r, letter in enumerate(word):
            freq[r][letter] += 1

    while True:
        worst_reelidx = None
        worst_letter = None
        worst_count = len(words)
        for r, reel in enumerate(freq):
            # Skip reels that already have too-few letters left
            if len(reel) <= letters_per_reel:
                continue

            for letter, count in reel.items():
                if count < worst_count:
                    worst_reelidx = r
                    worst_letter = letter
                    worst_count = count

        if worst_letter is None:
            # All the reels are done
            break

        # Discard any words containing this worst letter, and update counters
        # accordingly
        filtered_words = []
        for word in words:
            if word[worst_reelidx] == worst_letter:
                for r, letter in enumerate(word):
                    freq[r][letter] -= 1
                    if freq[r][letter] == 0:
                        del freq[r][letter]
            else:
                filtered_words.append(word)
        words = filtered_words

    for reel in freq:
        print(''.join(sorted(reel)))

    print("{} words found (~{:.1f}%)".format(
        len(words), len(words) / word_pool_size * 100))

Produziert:

BCDFGMPSTW
AEHILOPRTU
AEILNORSTU
ACDEKLNRST
DEHKLNRSTY
1273 words found (~30.5%)
Eevee
quelle
Was bedeutet der Prozentsatz?
Joe Z.
Prozentsatz der angegebenen Wörter, die mit dem vorgeschlagenen Satz von Walzen gemacht werden können
Eevee
Okay. (Whoa, ich habe gerade gesehen, wer Sie waren.)
Joe Z.
ha, kleine Welt.
Eevee
3

Mathematica , immer wieder 1275 Wörter ...

Dieser Code ist nicht Golf, da die Frage nicht dazu aufruft.

wordlist = Flatten @ Import @ "http://www.cs.duke.edu/~ola/ap/linuxwords";
shortlist = Select[ToLowerCase@wordlist, StringMatchQ[#, Repeated[LetterCharacter, {5}]] &];
string = "" <> Riffle[shortlist, ","];

set = "a" ~CharacterRange~ "z";
gb = RandomChoice[set, {5, 10}];

best = 0;
While[True,
  pos = Sequence @@ RandomInteger /@ {{1, 5}, {1, 10}};
  old = gb[[pos]];
  gb[[pos]] = RandomChoice @ set;
  If[best < #,
    best = #; Print[#, "   ", StringJoin /@ gb],
    gb[[pos]] = old
  ] & @ StringCount[string, StringExpression @@ Alternatives @@@ gb]
]

Die Wortanzahl entwickelt sich bei den meisten Läufen schnell (weniger als 10 Sekunden) auf 1275, wird aber nie darüber hinausgehen. Ich habe versucht, die Buchstaben mehr als einmal nacheinander durcheinander zu bringen, um aus einem theoretischen lokalen Maximum herauszukommen, aber es hat nie geholfen. Ich vermute sehr, dass 1275 das Limit für die angegebene Wortliste ist. Hier ist ein vollständiger Lauf:

36   {tphcehmqkt,agvkqxtnpy,nkehuaakri,nsibxpctio,iafwdyhone}

37   {tpicehmqkt,agvkqxtnpy,nkehuaakri,nsibxpctio,iafwdyhone}

40   {tpicehmqkt,agvkqxtnpy,nkehuaakri,nsibxpctio,iafldyhone}

42   {tpicehmqkt,agvkqxtnpy,nkehuaakri,nsfbxpctio,iafldyhone}

45   {tpicehmrkt,agvkqxtnpy,nkehuaakri,nsfbxpctio,iafldyhone}

48   {tpicehmrkt,agvkwxtnpy,nkehuaakri,nsfbxpctio,iafldyhone}

79   {tpicehmskt,agvkwxtnpy,nkehuaakri,nsfbxpctio,iafldyhone}

86   {tpicehmskt,agvkwxtnpy,nkehuaakri,esfbxpctio,iafldyhone}

96   {tpicehmskt,agvkwxtnpy,nkehuaokri,esfbxpctio,iafldyhone}

97   {tpicehmskt,agvkwxtnpy,nkehuaokri,esfbxpctio,ipfldyhone}

98   {tpicehmskv,agvkwxtnpy,nkehuaokri,esfbxpctio,ipfldyhone}

99   {tpicehmskv,agvkwxtnpy,nkehuaokri,esfbzpctio,ipfldyhone}

101   {tpicehmskv,agvkwxtnpy,nkehuaokri,esfhzpctio,ipfldyhone}

102   {tpicehmskv,agvkwxtnpy,nkehuaokri,esfhzpctno,ipfldyhone}

105   {tpicehmskv,agvkwxtnpy,nkehuaokri,esfhzmctno,ipfldyhone}

107   {tpicehmskn,agvkwxtnpy,nkehuaokri,esfhzmctno,ipfldyhone}

109   {tpgcehmskn,agvkwxtnpy,nkehuaokri,esfhzmctno,ipfldyhone}

115   {tpgcehmsan,agvkwxtnpy,nkehuaokri,esfhzmctno,ipfldyhone}

130   {tpgcehmsan,agvkwxtnpy,nkehuaokri,esfhzmctno,ipfldyhons}

138   {tpgcehmsan,agvkwxtnpy,nkehuaokri,esfhzmctno,ipfldytons}

143   {tpgcehmsab,agvkwxtnpy,nkehuaokri,esfhzmctno,ipfldytons}

163   {tpgcehmsab,auvkwxtnpy,nkehuaokri,esfhzmctno,ipfldytons}

169   {tpgcehmsab,auvkwctnpy,nkehuaokri,esfhzmctno,ipfldytons}

176   {tpgcehmsab,auvkwctnpy,nkehuaokri,esfhzmctno,ihfldytons}

189   {tpgcehmsab,auvkwchnpy,nkehuaokri,esfhzmctno,ihfldytons}

216   {tpgcehmsab,auvkwchnpy,nkehtaokri,esfhzmctno,ihfldytons}

220   {tpgcehmsab,auvkwthnpy,nkehtaokri,esfhzmctno,ihfldytons}

223   {tpgcehmsab,auvkwthnpy,nkehtaokri,esfhbmctno,ihfldytons}

234   {tpgcehmsab,auvkwthnpy,nkegtaokri,esfhbmctno,ihfldytons}

283   {tpgcehmsab,auvkwthnpy,nkegtaokri,esfhbrctno,ihfldytons}

285   {tpdcehmsab,auvkwthnpy,nkegtaokri,esfhbrctno,ihfldytons}

313   {tpdcehmsab,auvkwthnly,nkegtaokri,esfhbrctno,ihfldytons}

371   {tpdcehmsab,auvkethnly,nkegtaokri,esfhbrctno,ihfldytons}

446   {tpdcehmsab,auvoethnly,nkegtaokri,esfhbrctno,ihfldytons}

451   {tpdcehmslb,auvoethnly,nkegtaokri,esfhbrctno,ihfldytons}

465   {tpdcwhmslb,auvoethnly,nkegtaokri,esfhbrctno,ihfldytons}

545   {tpdcwhmslb,auioethnly,nkegtaokri,esfhbrctno,ihfldytons}

565   {tpdcwhmslb,auioethnly,nkegtaocri,esfhbrctno,ihfldytons}

571   {tpdcwhmslb,auioethnly,nkegtaocri,esfhwrctno,ihfldytons}

654   {tpdcwhmslb,auioethnly,nkegtaocri,esfhwrctno,ihfedytons}

671   {tpdcwhmslb,auioethnly,nkegtaocri,esfhirctno,ihfedytons}

731   {tpdcwhmslb,auioethnly,nkegtaocri,esfhirctno,ihredytons}

746   {tpdcwhmslb,arioethnly,nkegtaocri,esfhirctno,ihredytons}

755   {tpdcwhmslb,arioethnuy,nkegtaocri,esfhirctno,ihredytons}

772   {tpdcwhmslb,arioethnuy,nkegtaocri,ekfhirctno,ihredytons}

786   {tpdcwhmslb,arioethnuy,nkegtaocri,ekfhirctno,lhredytons}

796   {tpdcwhmslb,arioethnuy,nkegtaocri,ekfhgrctno,lhredytons}

804   {tpdcwhmslb,arioethwuy,nkegtaocri,ekfhgrctno,lhredytons}

817   {tpdcwhmslb,arioethwuy,nklgtaocri,ekfhgrctno,lhredytons}

834   {tpdcwhmslb,arioethwuy,nklgtaocri,ekfhdrctno,lhredytons}

844   {tpdcwhmslb,arioethwup,nklgtaocri,ekfhdrctno,lhredytons}

887   {tpdcwhmslb,arioethwup,nklgtaocri,ekshdrctno,lhredytons}

901   {tpdcwhmslb,arioethwup,nklgtaouri,ekshdrctno,lhredytons}

966   {tpdcwhmslb,arioethwup,nklgtaouri,elshdrctno,lhredytons}

986   {tpdcwhmsfb,arioethwup,nklgtaouri,elshdrctno,lhredytons}

1015   {tpdcwhmsfb,arioethwup,nklgtaouri,elsidrctno,lhredytons}

1039   {tpdcwhmsfb,arioethwup,nklgtaouri,elsidrctno,khredytons}

1051   {tpdcwhmsfb,arioethwup,nklgtaouri,elskdrctno,khredytons}

1055   {tpdcwhmsfb,arioethwup,nklgtaouri,elskdrctno,khredytlns}

1115   {tpdcwhmsfb,arioethwup,nelgtaouri,elskdrctno,khredytlns}

1131   {tpdcwhmsfb,arioethwup,nelwtaouri,elskdrctno,khredytlns}

1149   {tpdcwhmsfb,arioethwup,nelwtaouri,elskdrctna,khredytlns}

1212   {tpdcwhmsfb,arioelhwup,nelwtaouri,elskdrctna,khredytlns}

1249   {tpdcwhmsfb,arioelhwup,nelstaouri,elskdrctna,khredytlns}

1251   {tpgcwhmsfb,arioelhwup,nelstaouri,elskdrctna,khredytlns}

1255   {tpgcwdmsfb,arioelhwup,nelstaouri,elskdrctna,khredytlns}

1258   {tpgcwdmsfb,arioelhwup,nelstaouri,elskdrctna,khredytlas}

1262   {tpgcwdmsfb,arioelhwut,nelstaouri,elskdrctna,khredytlas}

1275   {tpgcwdmsfb,arioelhput,nelstaouri,elskdrctna,khredytlas}

Hier sind einige andere "gewinnende" Auswahlen:

{"cbpmsftgwd", "hriuoepatl", "euosrtanli", "clknsaredt", "yhlkdstare"}
{"wptdsgcbmf", "ohlutraeip", "erotauinls", "lknectdasr", "sytrhklaed"}
{"cftsbwgmpd", "ropilhtaue", "niauseltor", "clstnkdrea", "esdrakthly"}
{"smgbwtdcfp", "ihulpreota", "ianrsouetl", "ekndasctlr", "kehardytls"}

Wie Peter bemerkt, handelt es sich tatsächlich um die gleiche Lösung in unterschiedlichen Reihenfolgen. Sortiert:

{"bcdfgmpstw", "aehiloprtu", "aeilnorstu", "acdeklnrst", "adehklrsty"}
Mr.Wizard
quelle
@belisarius Danke! Mit ENABLE2k ist das interessanter .
Mr.Wizard
Ich habe über den NetworkFlow von Combinatorica nachgedacht, aber noch keinen sinnvollen Weg gefunden, ihn zu verwenden
Dr. belisarius
@belisarius Ich hoffe du findest einen Weg; Das würde ich gerne sehen.
Mr.Wizard
@belisarius übrigens mein Code für shortlistfühlt sich lang an, und obwohl dies nicht Golf ist, möchte ich etwas kürzer. Kannst du helfen?
Mr.Wizard
1
Ich denke, Ihre "gewinnenden" Auswahlen sind alle die gleiche Modulo-Permutation innerhalb der Wählscheiben.
Peter Taylor
2

Python, 1210 Wörter (~ 29%)

Vorausgesetzt, ich habe die Wörter dieses Mal richtig gezählt, ist dies etwas besser als die Lösung von FakeRainBrigand. Der einzige Unterschied besteht darin, dass ich jede Rolle der Reihe nach hinzufüge und dann alle Wörter aus der Liste entferne, die nicht mit der Rolle übereinstimmen, damit ich eine etwas bessere Verteilung für die nächsten Rollen erhalte. Aus diesem Grund gibt es genau die gleiche erste Rolle.

word_list = [line.upper()[:-1] for line in open('linuxwords.txt','r').readlines() if len(line) == 6]
cur_list = word_list
s = ['']*5
for i in range(5):
    count = [0]*26
    for j in range(26):
        c = chr(j+ord('A'))
        count[j] = len([x for x in cur_list if x[i] == c])
    s[i] = [chr(x+ord('A')) for x in sorted(range(26),lambda a,b: count[b] - count[a])[:10]]
    cur_list = filter(lambda x:x[i] in s[i],cur_list)
for e in s:
    print ''.join(e)
print len(cur_list)

Das Programm gibt aus

SBCAPFDTMG
AOREILUHTP
ARIOLENUTS
ENTLRCSAID
SEYDTKHRNL
1210
Pappschachtel
quelle
Schön, und 1210 funktioniert in meinem Checker.
Brigand
1

iPython ( 273 210 Bytes, 1115 Wörter)

1115/4176 * ~ 27%

Ich habe diese in iPython berechnet, aber mein Verlauf (um das Debuggen zu entfernen) sah folgendermaßen aus.

with open("linuxwords") as fin: d = fin.readlines()
x = [w.lower().strip() for w in d if len(w) == 6]
# Saving for later use:
# with open("5letter", "w") as fout: fout.write("\n".join(x))
from string import lowercase as low
low=lowercase + "'"
c = [{a:0 for a in low} for q in range(5)]
for w in x:
    for i, ch in enumerate(w):
        c[i][ch] += 1

[''.join(sorted(q, key=q.get, reverse=True)[:10]) for q in c]

Wenn wir für kurze Zeit gehen; Ich könnte es darauf zuschneiden.

x = [w.lower().strip() for w in open("l") if len(w)==6]
c=[{a:0 for a in"abcdefghijklmnopqrstuvwxyz'-"}for q in range(5)]
for w in[w.lower().strip()for w in open("l") if len(w)==6]:
 for i in range(5):c[i][w[i]]+=1
[''.join(sorted(q,key=q.get,reverse=True)[:10])for q in c]

Verkürzt:

c=[{a:0 for a in"abcdefghijklmnopqrstuvwxyz'-"}for q in range(5)]
for w in[w.lower() for w in open("l")if len(w)==6]:
 for i in range(5):c[i][w[i]]+=1
[''.join(sorted(q,key=q.get,reverse=True)[:10])for q in c]

Meine Ergebnisse waren: ['sbcapfdtmg', 'aoeirulhnt', 'aironeluts', 'etnlriaosc', 'seyrdtnlah'].

* Meine Mathematik für das 4176 ist möglicherweise etwas kurz, da Wörter mit Bindestrichen oder Apostrophen weggelassen werden

Räuber
quelle
1
Diese Lösung ist zwar eine gute Heuristik und wird wahrscheinlich eine gute Lösung zurückgeben, aber ich glaube nicht, dass die optimale Lösung garantiert wird. Der Grund ist, dass Sie die Einschränkungen zwischen den Rollen nicht erfassen: Sie behandeln jede Rolle als unabhängige Variable, wenn sie tatsächlich abhängig sind. Beispielsweise kann es vorkommen, dass Wörter mit dem häufigsten Anfangsbuchstaben eine große Abweichung in der Verteilung ihres zweiten Buchstabens aufweisen. Wenn dies der Fall ist, kann Ihre Lösung Kombinationen von Rollen erzeugen, die tatsächlich überhaupt keine Wörter zulassen.
ESultanik
1

Q.

? (todo) Wörter

Wörter sollten in einer Datei namens gespeichert werden words

(!:')10#/:(desc')(#:'')(=:')(+:)w@(&:)(5=(#:')w)&(&/')(w:(_:)(0:)`:words)in\:.Q.a

Läuft in ca. 170 ms auf meinem i7. Es analysiert die Wortliste und sucht an jeder Position nach dem häufigsten Buchstaben (wobei offensichtlich alle Nicht-Kandidaten herausgefiltert werden). Es ist eine faule, naive Lösung, die aber mit minimalem Code ein einigermaßen gutes Ergebnis liefert.

Ergebnisse:

"sbcapfdtmg"
"aoeirulhnt"
"aironeluts"
"etnlriaosc"
"seyrdtnlah"
Skeevey
quelle
Wie viele 5-Buchstaben-Wörter haben Sie gefunden?
DavidC
Ich habe die gleiche Sache in Python und bekam 16353.
cardboard_box
Ist das der gleiche gierige Algorithmus wie bei FakeRainBrigand?
Peter Taylor
1
@cardboard_box, dein Ergebnis ist definitiv falsch. Es gibt nicht so viele 5-Buchstaben-Wörter im Wörterbuch.
Peter Taylor
1
Ja, es ist 1115. Ich habe die Anzahl der richtigen Buchstaben in einem Wort anstelle der Anzahl der richtigen Wörter gezählt. Ich glaube, ich brauche noch einen Kaffee.
cardboard_box
0

Bearbeiten: Nachdem die Regeln geändert wurden, wird dieser Ansatz disqualifiziert. Ich werde es hier lassen, falls jemand Interesse hat, bis ich irgendwann dazu komme, es für die neuen Regeln zu modifizieren.

Python: 277 Zeichen

Ich bin mir ziemlich sicher, dass es sich bei der verallgemeinerten Version dieses Problems um NP-Hard handelt und für die Frage nicht die schnellste Lösung gesucht werden musste.

import itertools,string
w=[w.lower()[:-1] for w in open('w') if len(w)==6]
v=-1
for l in itertools.product(itertools.combinations(string.ascii_lowercase,10),repeat=5):
 c=sum(map(lambda d:sum(map(lambda i:i[0] in i[1],zip(d,l)))==5,w))
 if c>v:
  v=c
  print str(c)+" "+str(l)

Beachten Sie, dass ich die Wortlistendatei in "w" umbenannt habe, um einige Zeichen zu speichern.

Die Ausgabe ist die Anzahl der Wörter, die von einer bestimmten Konfiguration aus möglich sind, gefolgt von der Konfiguration selbst:

34 (('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'))
38 (('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'k'))
42 (('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'l'))
45 (('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'n'))
50 (('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'r'))
57 (('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 's'))
60 (('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'k', 's'))
64 (('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'l', 's'))
67 (('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'n', 's'))
72 (('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'r', 's'))
...

Die letzte Ausgabezeile vor dem Beenden des Programms ist garantiert die optimale Lösung.

ESultanik
quelle
Ich würde gerne eine C- oder ASM-Version Ihres Codes sehen, damit er dieses Jahr tatsächlich fertig wird :-) Oder führen Sie ihn zumindest bis 1116 aus. Können Sie ihn ohne Itertools schreiben, damit ich ihn auf Jython ausführen kann? ? (Schneller als normales Python, aber einfacher als Cython.)
Brigand
Vergiss das Jython Ding. Ich musste mir das Alpha schnappen. Es ist immer noch abgestürzt (zu viel Speicher), aber das scheint unvermeidlich.
Brigand
Ich bin mir ziemlich sicher, dass selbst wenn dies in der Baugruppe implementiert wäre, die Fertigstellung auf der aktuellen Hardware länger als mein Leben dauern würde :-P
ESultanik 21.01.13
Das Problem ist, dass ich über (26 wähle 10) ^ 5 ≈ 4.23 * 10 ^ 33 Möglichkeiten iteriere. Selbst wenn wir eine Möglichkeit pro Nanosekunde testen könnten, würde es ungefähr das 10- bis 7-fache des aktuellen Zeitalters des Universums dauern, um fertig zu werden.
ESultanik
1
Es gibt zwei Zeichen, die in keinem Wort in der angegebenen Wortliste an fünfter Stelle stehen, sodass Sie die Anzahl der Möglichkeiten um den Faktor 4 reduzieren können. So erhielt ich in meinem Kommentar zu "etwa 110,3 Bit" die Frage.
Peter Taylor