Je voulais voir les réponses à cette question (aujourd'hui disparue) , mais elle n'a jamais été corrigée / améliorée.
Étant donné un ensemble de dés Boggle à 6 faces (configuration volée à cette question ), déterminez en deux minutes de temps de traitement quelle configuration de carte permettra le score le plus élevé possible. (c.-à-d. quels dés dans quel endroit avec quel côté vers le haut permet le plus grand pool de mots de score?)
OBJECTIF
Votre code ne devrait pas durer plus de 2 minutes (120 secondes). À ce moment, il devrait s'arrêter automatiquement et imprimer les résultats.
Le score final du défi sera le score Boggle moyen de 5 exécutions du programme.
- En cas d'égalité, le gagnant sera celui qui aura trouvé le plus de mots.
- S'il y a toujours égalité, le gagnant sera celui qui aura trouvé le plus de mots longs (8+) .
RÈGLES / CONTRAINTES
Il s'agit d'un défi de code; la longueur du code n'est pas pertinente.
Veuillez vous référer à ce lien pour une liste de mots (utilisez la
ISPELL "english.0"
liste - il manque des mots assez communs à la liste SCOWL).- Cette liste peut être référencée / importée / lue dans votre code comme vous le souhaitez.
- Seuls les mots correspondant à l'expression régulière
^([a-pr-z]|qu){3,16}$
seront comptés. (Seules les lettres minuscules, 3-16 caractères, qu doivent être utilisées comme une unité.)
Les mots sont formés en reliant des lettres adjacentes (horizontales, verticales et diagonales) pour épeler les mots dans le bon ordre, sans utiliser un seul dé plus d'une fois dans un seul mot.
- Les mots doivent contenir 3 lettres ou plus; des mots plus courts ne rapporteront aucun point.
- Les lettres en double sont acceptables, mais pas les dés.
- Les mots qui s'étendent sur les bords / se croisent d'un côté de la planche à l'autre ne sont pas autorisés.
Le score final Boggle ( pas de défi ) est le total des valeurs de points pour tous les mots trouvés.
- La valeur en points attribuée à chaque mot est basée sur la longueur du mot. (voir ci-dessous)
- Les règles Boggle normales déduiraient / remettraient les mots trouvés par un autre joueur. Supposons ici qu'aucun autre joueur n'est impliqué et que tous les mots trouvés comptent pour le score total.
- Cependant, les mots trouvés plus d'une fois dans la même grille ne doivent être comptés qu'une seule fois.
Votre fonction / programme doit TROUVER l'arrangement optimal; simplement coder en dur une liste prédéterminée ne fera pas l'affaire.
Votre sortie doit être une grille 4x4 de votre plateau de jeu idéal, une liste de tous les mots trouvés pour ce plateau et le score Boggle correspondant à ces mots.
CONFIGURATION DE LA MATRICE
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
TABLEAU DE NOTATION STANDARD DE BOGGLE
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.
EXEMPLE DE SORTIE
A L O J
V U T S
L C H E
G K R X
CUT
THE
LUCK
HEX
....
140 points
Si des éclaircissements supplémentaires sont nécessaires, veuillez demander!
la source
4527
(1414
nombre total de mots), trouvé ici: ai.stanford.edu/~chuongdo/boggle/index.html^([a-pr-z]|qu){3,16}$
(qui exclurait à tort les mots de 3 lettres avec qu, mais il n'y en a pas).Réponses:
C, en moyenne
500+15001750 pointsIl s'agit d'une amélioration relativement mineure par rapport à la version 2 (voir ci-dessous pour les notes sur les versions précédentes). Il y a deux parties. Premièrement: au lieu de sélectionner des tableaux au hasard dans le pool, le programme itère maintenant sur chaque tableau du pool, en les utilisant à tour de rôle avant de retourner en haut du pool et de répéter. (Étant donné que le pool est en cours de modification pendant cette itération, il y aura toujours des cartes qui seront choisies deux fois de suite, ou pire, mais ce n'est pas un problème grave.) Le deuxième changement est que le programme suit maintenant lorsque le pool change et si le programme dure trop longtemps sans améliorer le contenu du pool, il détermine que la recherche est "bloquée", vide le pool et recommence avec une nouvelle recherche. Il continue de le faire jusqu'à ce que les deux minutes soient écoulées.
J'avais initialement pensé que j'utiliserais une sorte de recherche heuristique pour dépasser la plage des 1500 points. Le commentaire de @ mellamokb à propos d'un tableau de 4527 points m'a amené à supposer qu'il y avait beaucoup de place pour l'amélioration. Cependant, nous utilisons une liste de mots relativement petite. Le tableau de 4527 points marquait en utilisant YAWL, qui est la liste de mots la plus inclusive - elle est encore plus grande que la liste de mots officielle du Scrabble américain. Dans cet esprit, j'ai réexaminé les planches que mon programme avait trouvées et j'ai remarqué qu'il semblait y avoir un ensemble limité de planches au-dessus de 1700 environ. Ainsi, par exemple, j'ai eu plusieurs pistes qui avaient découvert une planche marquant 1726, mais c'était toujours exactement la même planche que celle trouvée (en ignorant les rotations et les réflexions).
Comme autre test, j'ai exécuté mon programme en utilisant YAWL comme dictionnaire, et il a trouvé la carte à 4527 points après environ une douzaine d'exécutions. Compte tenu de cela, je fais l'hypothèse que mon programme est déjà à la limite supérieure de l'espace de recherche, et donc la réécriture que je prévoyais introduirait une complexité supplémentaire pour très peu de gain.
Voici ma liste des cinq tableaux les mieux notés que mon programme a trouvés en utilisant la liste de
english.0
mots:Ma conviction est que le 1772 "grep board" (comme je l'ai pris pour l'appeler), avec 531 mots, est le tableau le plus performant possible avec cette liste de mots. Plus de 50% des parcours de deux minutes de mon programme se terminent avec ce forum. J'ai également laissé mon programme fonctionner pendant la nuit sans qu'il ne trouve rien de mieux. Donc, s'il existe un tableau avec un score plus élevé, il devrait probablement avoir un aspect qui vainc la technique de recherche du programme. Un tableau dans lequel chaque petite modification possible de la mise en page provoque une énorme baisse du score total, par exemple, pourrait ne jamais être découvert par mon programme. Mon intuition est qu'il est très peu probable qu'un tel conseil existe.
Notes pour la version 2 (9 juin)
Voici une façon d'utiliser la version initiale de mon code comme point de départ. Les modifications apportées à cette version se composent de moins de 100 lignes, mais ont triplé le score de jeu moyen.
Dans cette version, le programme maintient un "pool" de candidats, composé des N tableaux les mieux notés que le programme a généré jusqu'à présent. Chaque fois qu'un nouveau tableau est généré, il est ajouté au pool et le tableau le moins bien noté dans le pool est supprimé (qui peut très bien être le tableau qui vient d'être ajouté, si son score est inférieur à celui qui existe déjà). Le pool est initialement rempli de cartes générées aléatoirement, après quoi il conserve une taille constante tout au long du programme.
La boucle principale du programme consiste à sélectionner un tableau aléatoire dans le pool et à le modifier, à déterminer le score de ce nouveau tableau, puis à le placer dans le pool (s'il réussit assez bien). De cette façon, le programme perfectionne continuellement les tableaux à score élevé. L'activité principale consiste à apporter des améliorations progressives et incrémentielles, mais la taille du pool permet également au programme de trouver des améliorations en plusieurs étapes qui aggravent temporairement le score d'un conseil avant de pouvoir l'améliorer.
Généralement, ce programme trouve un bon maximum local assez rapidement, après quoi un meilleur maximum est probablement trop éloigné pour être trouvé. Et donc, encore une fois, il est inutile d'exécuter le programme pendant plus de 10 secondes. Cela pourrait être amélioré, par exemple en demandant au programme de détecter cette situation et de lancer une nouvelle recherche avec un nouveau groupe de candidats. Cependant, cela ne représenterait qu'une augmentation marginale. Une technique de recherche heuristique appropriée serait probablement une meilleure voie d'exploration.
(Note latérale: j'ai vu que cette version générait environ 5 000 tableaux / seconde. Comme la première version faisait généralement 20 000 tableaux / seconde, j'étais initialement inquiet. Cependant, lors du profilage, j'ai découvert que le temps supplémentaire était consacré à la gestion de la liste de mots. En d'autres termes, cela est entièrement dû au fait que le programme a trouvé beaucoup plus de mots par tableau. À la lumière de cela, j'ai envisagé de changer le code pour gérer la liste de mots, mais étant donné que ce programme n'utilise que 10 des 120 secondes allouées, telles que une optimisation serait très prématurée.)
Notes pour la version 1 (2 juin)
Il s'agit d'une solution très, très simple. Tout ce qu'il fait, il génère des tableaux aléatoires, puis après 10 secondes, il sort celui avec le score le plus élevé. (Je suis passé par défaut à 10 secondes car les 110 secondes supplémentaires autorisées par la spécification du problème n'améliorent généralement pas la solution finale trouvée suffisamment pour mériter d'être attendue.) C'est donc extrêmement stupide. Cependant, il dispose de toutes les infrastructures nécessaires pour constituer un bon point de départ pour une recherche plus intelligente, et si quelqu'un souhaite en faire usage avant la date limite, je les encourage à le faire.
Le programme commence par lire le dictionnaire dans une arborescence. (Le formulaire n'est pas aussi optimisé qu'il pourrait l'être, mais il est plus que suffisant pour ces fins.) Après une autre initialisation de base, il commence alors à générer des tableaux et à les noter. Le programme examine environ 20 000 planches par seconde sur ma machine, et après environ 200 000 planches, l'approche aléatoire commence à tourner à sec.
Puisqu'une seule carte est réellement évaluée à un moment donné, les données de notation sont stockées dans des variables globales. Cela me permet de minimiser la quantité de données constantes qui doivent être transmises comme arguments aux fonctions récursives. (Je suis sûr que cela donnera des ruches à certaines personnes, et je m'excuse pour elles.) La liste de mots est stockée sous forme d'arbre de recherche binaire. Chaque mot trouvé doit être recherché dans la liste de mots, afin que les mots en double ne soient pas comptés deux fois. La liste de mots n'est nécessaire que pendant le processus d'évaluation, elle est donc supprimée une fois la partition trouvée. Ainsi, à la fin du programme, le tableau choisi doit être noté à nouveau, afin que la liste de mots puisse être imprimée.
Fait amusant: Le score moyen pour un tableau Boggle généré de manière aléatoire, tel que marqué par
english.0
, est de 61,7 points.la source
VBA (moyenne actuellement comprise entre 80 et 110 points, inachevé)
Voici mon processus de travail, mais c'est loin d'être le meilleur possible; mon meilleur score absolu trouvé sur n'importe quelle planche après de nombreux tests est d'environ 120. Il doit encore y avoir un meilleur nettoyage général et je suis sûr qu'il y a plus d'efficacité à gagner à plusieurs endroits.
Cela semble probablement horrible pour certains d'entre vous, mais comme je l'ai dit, WIP. Je suis très ouvert aux critiques constructives ! Désolé pour le corps très long ...
Module de classe de dés :
Module de classe d'arbre :
Module de classe TreeNode :
Module principal :
la source
Aperçu rapide de la taille de l'espace de recherche.
Réduire pour exclure la répétition sur chaque dé.
@breadbox stocke le dictionnaire en tant que vérification de la table de hachage O (1).
ÉDITER
Meilleure planche (j'en ai été témoin jusqu'à présent)
la source
Mon entrée est ici sur Dream.In.Code ~ 30 ms par recherche de carte (sur une machine à 2 cœurs, devrait être plus rapide avec plus de cœurs)
la source
:
enhttp://
. ;-).NET
àVBA
n'est pas trop difficile.