Ich war daran interessiert, die Antworten auf diese (jetzt nicht mehr existierende) Frage zu sehen , aber sie wurde nie korrigiert / verbessert.
Bestimmen Sie bei einem Satz 6-seitiger Boggle- Würfel (Konfiguration aus dieser Frage gestohlen ) in zwei Minuten Verarbeitungszeit, welche Board-Konfiguration die höchstmögliche Punktzahl ermöglicht. (dh welche Würfel an welcher Stelle mit welcher Seite nach oben ermöglichen den größten Wertungswortpool?)
ZIELSETZUNG
Ihr Code sollte nicht länger als 2 Minuten (120 Sekunden) ausgeführt werden. Zu diesem Zeitpunkt sollte die Ausführung automatisch unterbrochen und die Ergebnisse gedruckt werden.
Die endgültige Herausforderungspunktzahl ist die durchschnittliche Boggle-Punktzahl von 5 Programmläufen.
- Bei einem Gleichstand gewinnt der Algorithmus, der mehr Wörter gefunden hat.
- Falls es immer noch einen Gleichstand gibt, gewinnt der Algorithmus, der mehr lange (8+) Wörter gefunden hat.
REGELN / EINSCHRÄNKUNGEN
Dies ist eine Code-Herausforderung. Codelänge ist irrelevant.
Unter diesem Link finden Sie eine Wortliste (verwenden Sie die
ISPELL "english.0"
Liste - in der SCOWL-Liste fehlen einige häufig verwendete Wörter).- Diese Auflistung kann nach Belieben in Ihrem Code referenziert / importiert / gelesen werden.
- Es werden nur Wörter gezählt, die mit dem regulären Ausdruck übereinstimmen
^([a-pr-z]|qu){3,16}$
. (Nur Kleinbuchstaben mit 3 bis 16 Zeichen, qu, dürfen als Einheit verwendet werden.)
Wörter werden durch Verknüpfen benachbarter Buchstaben (horizontal, vertikal und diagonal) gebildet, um Wörter in der richtigen Reihenfolge zu buchstabieren, ohne einen einzelnen Würfel mehr als einmal in einem einzelnen Wort zu verwenden.
- Wörter müssen 3 Buchstaben oder länger sein; Kürzere Wörter bringen keine Punkte.
- Doppelbuchstaben sind zulässig, nur keine Würfel.
- Wörter, die sich über die Kanten erstrecken, sind nicht erlaubt.
Die endgültige Punktzahl für Boggle ( keine Herausforderung ) ist die Summe der Punktwerte für alle gefundenen Wörter.
- Der für jedes Wort zugewiesene Punktwert basiert auf der Länge des Wortes. (siehe unten)
- Normale Boggle-Regeln würden Wörter, die von einem anderen Spieler gefunden wurden, abziehen / rabattieren. Angenommen, es sind keine anderen Spieler beteiligt, und alle gefundenen Wörter werden für die Gesamtpunktzahl berücksichtigt.
- Wörter, die mehr als einmal im selben Raster gefunden wurden, sollten jedoch nur einmal gezählt werden.
Ihre Funktion / Programm muss FIND die optimale Anordnung; Eine vorgegebene Liste einfach hart zu codieren, reicht nicht aus.
Ihre Ausgabe sollte ein 4x4-Raster Ihres idealen Spielbretts sein, eine Liste aller gefundenen Wörter für dieses Brett und die Boggle-Punktzahl, die mit diesen Wörtern übereinstimmt.
DIE KONFIGURATION
A A E E G N
E L R T T Y
A O O T T W
A B B J O O
E H R T V W
C I M O T U
D I S T T Y
E I O S S T
D E L R V Y
A C H O P S
H I M N Qu U
E E I N S U
E E G H N W
A F F K P S
H L N N R Z
D E I L R X
STANDARD BOGGLE SCORING TABELLE
Word length => Points
<= 2 - 0 pts
3 - 1
4 - 1
5 - 2
6 - 3
7 - 5
>= 8 - 11 pts
*Words using the "Qu" die will count the full 2 letters for their word, not just the 1 die.
BEISPIEL AUSGABE
A L O J
V U T S
L C H E
G K R X
CUT
THE
LUCK
HEX
....
140 points
Wenn weitere Abklärungen erforderlich sind, fragen Sie bitte!
quelle
4527
(1414
Gesamt Wörter), finden Sie hier: ai.stanford.edu/~chuongdo/boggle/index.html^([a-pr-z]|qu){3,16}$
(was fälschlicherweise Wörter mit drei Buchstaben mit qu ausschließen würde, aber es gibt keine).Antworten:
C, im Durchschnitt
mehr als15001750 PunkteDies ist eine relativ geringfügige Verbesserung gegenüber Version 2 (siehe unten für Hinweise zu früheren Versionen). Es gibt zwei Teile. Erstens: Anstatt Bretter zufällig aus dem Pool auszuwählen, durchläuft das Programm nun alle Bretter im Pool und verwendet sie nacheinander, bevor es zum oberen Rand des Pools zurückkehrt und sie wiederholt. (Da der Pool während dieser Iteration geändert wird, gibt es immer noch Boards, die zweimal hintereinander oder noch schlimmer ausgewählt werden. Dies ist jedoch kein ernstes Problem.) Die zweite Änderung besteht darin, dass das Programm jetzt nachverfolgt, wann sich der Pool ändert , und wenn das Programm zu lange läuft, ohne den Poolinhalt zu verbessern, wird festgestellt, dass die Suche "angehalten" hat, der Pool geleert wird und eine neue Suche gestartet wird. Dies wird fortgesetzt, bis die zwei Minuten abgelaufen sind.
Ich hatte ursprünglich gedacht, dass ich eine Art heuristische Suche durchführen würde, um über den 1500-Punkte-Bereich hinauszukommen. @ mellamokbs Kommentar zu einem 4527-Punkte-Board hat mich zu der Annahme veranlasst, dass es viel Raum für Verbesserungen gibt. Wir verwenden jedoch eine relativ kleine Wortliste. Das 4527-Punkte-Board bewertete mit YAWL, der umfassendsten Wortliste auf dem Markt - sie ist sogar größer als die offizielle US-Scrabble-Wortliste. In diesem Sinne überprüfte ich die Boards, die mein Programm gefunden hatte, erneut und stellte fest, dass es eine begrenzte Anzahl von Boards über 1700 zu geben schien. So hatte ich zum Beispiel mehrere Läufe, bei denen ein Board gefunden wurde, das 1726 Punkte erzielte, aber es wurde immer genau dasselbe Board gefunden (ohne Berücksichtigung von Rotationen und Reflexionen).
Als weiteren Test habe ich mein Programm mit YAWL als Wörterbuch ausgeführt und nach etwa einem Dutzend Durchläufen die 4527-Punkte-Karte gefunden. Angesichts dessen gehe ich davon aus, dass sich mein Programm bereits an der oberen Grenze des Suchbereichs befindet und daher die geplante Neufassung zusätzliche Komplexität mit sehr geringem Gewinn einbringen würde.
Hier ist meine Liste der fünf am
english.0
besten bewerteten Boards, die mein Programm anhand der Wortliste gefunden hat:Meiner Meinung nach ist das "Grep-Board" von 1772 (wie ich es nenne) mit 531 Wörtern das Board mit der höchsten Punktzahl, das mit dieser Wortliste möglich ist. Über 50% der zweiminütigen Läufe meines Programms enden mit diesem Board. Ich habe mein Programm auch über Nacht laufen lassen, ohne dass es etwas Besseres findet. Wenn es also ein Board mit höherer Punktzahl gibt, muss es wahrscheinlich einen Aspekt haben, der die Suchtechnik des Programms zunichte macht. Ein Board, bei dem jede mögliche kleine Änderung des Layouts zum Beispiel zu einem großen Rückgang der Gesamtpunktzahl führt, könnte von meinem Programm möglicherweise nie entdeckt werden. Meiner Meinung nach ist es sehr unwahrscheinlich, dass ein solches Board existiert.
Anmerkungen zu Version 2 (9. Juni)
Hier ist eine Möglichkeit, die ursprüngliche Version meines Codes als Ausgangspunkt zu verwenden. Die Änderungen an dieser Version bestehen aus weniger als 100 Zeilen, haben jedoch die durchschnittliche Spielpunktzahl verdreifacht.
In dieser Version verwaltet das Programm einen "Pool" von Kandidaten, bestehend aus den N Boards mit der höchsten Punktzahl, die das Programm bisher generiert hat. Jedes Mal, wenn ein neues Board erstellt wird, wird es dem Pool hinzugefügt und das Board mit der niedrigsten Punktzahl aus dem Pool entfernt (dies kann sehr gut das Board sein, das gerade hinzugefügt wurde, wenn seine Punktzahl niedriger ist als das, was bereits vorhanden ist). Der Pool wird anfänglich mit zufällig generierten Boards gefüllt, wonach er während des gesamten Programmablaufs eine konstante Größe behält.
Die Hauptschleife des Programms besteht darin, eine zufällige Karte aus dem Pool auszuwählen und zu ändern, die Punktzahl dieser neuen Karte zu bestimmen und sie dann in den Pool zu legen (wenn sie gut genug punktet). Auf diese Weise werden die Highscoring-Boards ständig weiterentwickelt. Die Hauptaktivität besteht darin, schrittweise, inkrementelle Verbesserungen vorzunehmen. Die Größe des Pools ermöglicht es dem Programm jedoch auch, Verbesserungen in mehreren Schritten zu finden, die die Punktzahl eines Boards vorübergehend verschlechtern, bevor es sie verbessern kann.
Typischerweise findet dieses Programm ein gutes lokales Maximum ziemlich schnell, wonach vermutlich ein besseres Maximum zu weit entfernt ist, um gefunden zu werden. Und so hat es wieder wenig Sinn, das Programm länger als 10 Sekunden laufen zu lassen. Dies könnte verbessert werden, indem z. B. das Programm diese Situation erkennt und eine neue Suche mit einem neuen Kandidatenpool startet. Dies würde jedoch nur einen geringfügigen Anstieg bedeuten. Eine geeignete heuristische Suchtechnik wäre wahrscheinlich eine bessere Möglichkeit zur Erkundung.
(Randnotiz: Ich sah, dass diese Version ungefähr 5.000 Boards / Sek. Erzeugte. Da die erste Version normalerweise 20.000 Boards / Sek. Erzeugte, war ich anfangs besorgt. Als ich ein Profil erstellte, stellte ich jedoch fest, dass die zusätzliche Zeit für die Verwaltung der Wortliste aufgewendet wurde. Mit anderen Worten, es war ganz darauf zurückzuführen, dass das Programm so viel mehr Wörter pro Board gefunden hat. Aus diesem Grund habe ich überlegt, den Code zu ändern, um die Wortliste zu verwalten, aber da dieses Programm nur 10 seiner zugewiesenen 120 Sekunden verwendet, z Eine Optimierung wäre sehr verfrüht.)
Anmerkungen zu Version 1 (2. Juni)
Dies ist eine sehr, sehr einfache Lösung. Alles, was es macht, sind zufällige Bretter, und nach 10 Sekunden gibt es das mit der höchsten Punktzahl aus. (Ich habe standardmäßig 10 Sekunden verwendet, da die zusätzlichen 110 Sekunden, die in der Problemspezifikation angegeben sind, in der Regel nicht die endgültige Lösung verbessern, auf die es sich zu warten lohnt.) Es ist also extrem dumm. Es verfügt jedoch über die gesamte Infrastruktur, um einen guten Ausgangspunkt für eine intelligentere Suche zu schaffen, und wenn jemand es vor Ablauf der Frist nutzen möchte, ermutige ich ihn, dies zu tun.
Das Programm beginnt mit dem Einlesen des Wörterbuchs in eine Baumstruktur. (Das Formular ist nicht ganz so optimiert wie es sein könnte, aber es ist mehr als gut genug für diese Zwecke.) Nach einer weiteren grundlegenden Initialisierung werden Bretter generiert und bewertet. Das Programm untersucht ungefähr 20.000 Boards pro Sekunde auf meiner Maschine, und nach ungefähr 200.000 Boards beginnt der Zufallsansatz, trocken zu laufen.
Da zu jedem Zeitpunkt nur eine Karte tatsächlich ausgewertet wird, werden die Scoring-Daten in globalen Variablen gespeichert. Dadurch kann ich die Menge der konstanten Daten minimieren, die als Argumente an die rekursiven Funktionen übergeben werden müssen. (Ich bin sicher, dass dies einigen Leuten Bienenstöcke geben wird, und ich entschuldige mich bei ihnen.) Die Wortliste wird als binärer Suchbaum gespeichert. Jedes gefundene Wort muss in der Wortliste nachgeschlagen werden, damit doppelte Wörter nicht doppelt gezählt werden. Die Wortliste wird jedoch nur während des Auswertungsprozesses benötigt, sodass sie gelöscht wird, nachdem die Punktzahl gefunden wurde. Am Ende des Programms muss die gewählte Tafel also noch einmal gewertet werden, damit die Wortliste ausgedruckt werden kann.
Unterhaltsame Tatsache: Die durchschnittliche Punktzahl für ein zufällig generiertes Boggle-Board
english.0
beträgt 61,7 Punkte.quelle
VBA (Durchschnitt derzeit im Bereich von 80-110 Punkten, unvollendet)
Hier ist mein Arbeitsprozess, aber er ist alles andere als der bestmögliche. Mein absoluter Bestwert, den ich nach vielen Testläufen auf einem Board gefunden habe, liegt bei etwa 120. Es muss noch etwas besser aufgeräumt werden, und ich bin mir sicher, dass es an mehreren Stellen mehr Effizienz gibt.
Dies sieht für einige von Ihnen wahrscheinlich schrecklich aus, aber wie gesagt, WIP. Ich bin sehr offen für konstruktive Kritik! Entschuldigung für den sehr langen Körper ...
Würfelklassen-Modul :
Baumklassenmodul :
TreeNode-Klassenmodul :
Hauptmodul :
quelle
Schneller Blick auf die Größe des Suchraums.
Reduzierung, um die Wiederholung auf jedem Würfel auszuschließen.
@breadbox speichert das Wörterbuch als Hash Table O (1) -Prüfung.
BEARBEITEN
Bestes Board (das ich bisher gesehen habe)
quelle
Mein Eintrag ist hier auf Dream.In.Code ~ 30ms pro Board-Suche (auf einer 2-Core-Maschine sollte mit mehr Kernen schneller sein)
quelle
:
inhttp://
. ;-).NET
zuVBA
ist nicht zu schwer.