Ecrivez le programme le plus court qui résout le cube de Rubik (3 * 3 * 3) dans un délai raisonnable et se déplace (par exemple, maximum 5 secondes sur votre machine et moins de 1 000 déplacements).
L'entrée est au format:
UF UR UB UL DF DR DB DL FR FL BR BL UFR URB UBL ULF DRF DFL DLB DBR
(cette entrée particulière représente le cube résolu).
Les 12 premières chaînes de 2 caractères sont les arêtes des positions UF, UR, ... BL (U = haut, F = avant, R = droite, B = arrière, L = gauche, D = bas), puis les 8 suivantes Les chaînes de 3 caractères sont les coins des positions UFR, URB, ... DBR.
La sortie devrait donner une séquence de mouvements dans ce format:
D+ L2 U+ F+ D+ L+ D+ F+ U- F+
Où D1 ou D + représente une rotation de 90 degrés de la face D (vers le bas) dans le sens des aiguilles d'une montre, L2 d'une rotation de 180 degrés de la face L, U3 ou U- représente une rotation de 90 degrés de la face U dans le sens inverse des aiguilles d'une montre.
Les lettres ne sont pas sensibles à la casse et les espaces sont facultatifs.
Par exemple, la sortie ci-dessus est correcte pour l'entrée suivante:
RU LF UB DR DL BL UL FU BD RF BR FD LDF LBD FUL RFD UFR RDB UBL RBU
Pour plus de détails, veuillez vous reporter au concours de cube de Tomas Rokicki , sauf que la notation se fera directement par la taille du fichier, comme un problème de golf classique. Un testeur en ligne est également inclus.
Pour référence, la solution la plus courte déjà écrite est la dernière entrée dans la liste des gagnants du concours de cube
Pour ceux qui ont du mal à visualiser le format de mise en page:
0-1 2-3 4-5 6-7 8-9 10-11 12-13 14-15 16-17 18-19 20-21 22-23 24-25-26 27-28-29 30-31-32 33-34-35 36-37-38 39-40-41 42-43-44 45-46-47
UF UR UB UL DF DR DB DL FR FL BR BL UFR URB UBL ULF DRF DFL DLB DBR
Front:
+-------+-------+-------+
/ / / /|
/ 30 / 4 / 27 / |
+-------+-------+-------+ |
/ / / /|28+
/ 6 / / 2 / | /|
+-------+-------+-------+ |/ |
/ / / /|3 + |
/ 33 / 0 / 24 / | /|21+
+-------+-------+-------+ |/ | /|
| | | |26+ |/ |
| 35 | 1 | 25 | /| + |
| | | |/ | /|47+
+-------+-------+-------+ |/ | /
| | | |17+ |/
| 18 | | 16 | /|11+
| | | |/ | /
+-------+-------+-------+ |/
| | | |37+
| 40 | 9 | 38 | /
| | | |/
+-------+-------+-------+
Hidden faces:
+-------+-------+-------+
/| | | |
/ | 31 | 5 | 29 |
+ | | | |
/|32+-------+-------+-------+
/ | /| | | |
+ |/ | 22 | | 20 |
/|7 + | | | |
/ | /|23+-------+-------+-------+
+ |/ | /| | | |
|34+ |/ | 44 | 13 | 46 |
| /| + | | | |
|/ | /|43+-------+-------+-------+
+ |/ | / / / /
|19+ |/ 42 / 12 / 45 /
| /|15+-------+-------+-------+
|/ | / / / /
+ |/ 14 / / 10 /
|41+-------+-------+-------+
| / / / /
|/ 39 / 8 / 36 /
+-------+-------+-------+
la source
Réponses:
C ++ - 1123
Comme personne n’avait posté de réponse à ce jour, j’ai décidé de simplifier et de mettre au golf ma solution de 2004. C'est encore loin derrière le plus court que j'ai mentionné dans la question.
Ce n'est pas aléatoire, mais cela ne se fait pas non plus directement. Il résout les bords en premier, puis les coins. À chaque étape, il essaie diverses combinaisons allant jusqu'à 4 algorithmes et des tours de visage simples (séquentiellement, pas au hasard), jusqu'à ce qu'il trouve une amélioration du nombre de morceaux résolus, puis se répète jusqu'à ce qu'il soit résolu. Il utilise 2 algorithmes pour les arêtes et 2 pour les angles, traduits dans toutes les positions du cube.
Exemple de sortie pour
RU LF UB DR DL BL UL FU BD RF BR FD LDF LBD FUL RFD UFR RDB UBL RBU
:L2F3B2F3B1U3F1B3R2F3B1U3F1B3D2F2L3D2L1U2B1L1R3U2R1L3B1U2R1U2L1F1B3U2B1F3L1U2L3R1D3L1R3B2L3R1D3L1R3L3R1D3L1R3B2L3R1D3L1R3B3F1D3B1F3R2B3F1D3B1F3U2F3L3R1B3L1R3U2L3R1B3L1R3F1D2F1L1R3D2R1L3F1D2F3L2U1B1F3L2F1B3U1L2R3L1F3R1L3U2R3L1F3R1L3U1F2U1L1R3F2R1L3U1F2U3L3U3L1U3L3U2L1R1U1R3U1R1U2R3F3U3F1U3F3U2F1B1U1B3U1B1U2B3L1B3R3B1L3B3R1B1B3D3B1D3B3D2B1F1D1F3D1F1D2F3R1F3L3F1R3F3L1F1R3B3R1B3R3B2R1L1B1L3B1L1B2L3R1D3L3D1R3D3L1D1B3D3B1D3B3D2B1F1D1F3D1F1D2F3U3R3U1R3U3R2U1D1R1D3R1D1R2D3
(234 coups, 0,3 sec ici)
la source
Python 1166 octets
Une quantité considérable d’espaces a été laissée pour des raisons de lisibilité. La taille est mesurée après suppression de cette espaces, et en changeant différents niveaux d'indentation à
Tab
,Tab
Space
,Tab
Tab
, etc. J'ai aussi évité tout le golf qui a affecté la performance de manière trop drastique.Exemple d'utilisation:
Ceci est une implémentation de l'algorithme de Thistlethwaite, utilisant une recherche IDA * à résoudre pour chaque étape. Étant donné que toutes les tables heuristiques doivent être calculées à la volée, plusieurs compromis ont été faits, divisant généralement une heuristique en deux ou plusieurs parties de taille sensiblement égale. Cela accélère le calcul des tables heuristiques des centaines de fois, tout en ralentissant légèrement la phase de recherche, mais il peut être important en fonction de l'état initial du cube.
Indice variable
T
- la table heuristique principale.S
- un état de cube résolu. Chaque pièce individuelle est stockée sous forme de masque de bits, représenté par un caractère. Un vecteur d'orientation résolu est défini comme le vecteur zéro.I
- les différents rebondissements, dans l'ordre dans lequel ils sont éliminés de l'espace de recherche.G
- les groupes de permutations de torsion, stockés sous forme de paires à échanger. Chaque octet de la chaîne compressée code pour une paire. Chaque torsion nécessite six échanges: trois pour le cycle de bord et trois pour le cycle de coin. La chaîne compressée contient uniquement des caractères ASCII imprimables (caractères 32 à 126).M
- une fonction qui effectue un mouvement, donné par G.N
- convertit une permutation de quatre objets en un nombre, à des fins de codage.H
- calcule la valeur heuristique pour l'état de cube donné, utilisé pour rechercher la profondeur de déplacement à partir de T.P
- effectuer une recherche à une profondeur unique d'une phase de l'algorithme.s
- l'état de permutation du cube en entrée.o
- le vecteur d'orientation du cube en entrée.Performance
En utilisant le jeu de données de Tomas Rokicki , ce script a enregistré une moyenne de 16,02 twists par résolution (maximum 35), avec un temps moyen de 472 ms (i5-3330 CPU @ 3.0 Ghz, PyPy 1.9.0). Le temps de résolution minimum était de 233 ms avec un maximum de 2,97 secondes, écart type de 0,488. En utilisant les directives de notation du concours (les espaces ne sont pas comptés, les mots-clés et les identifiants comptent pour un octet pour une longueur de 870), le score total aurait été de 13 549.
Pour les 46 derniers cas (les états aléatoires), la moyenne est de 30,83 torsions par résolution, avec un temps moyen de 721 ms.
Notes sur l'algorithme de Thistlethwaite
Pour le bénéfice de tous ceux qui voudraient tenter de mettre en œuvre l'algorithme de Thistlethwaite , voici une brève explication.
L'algorithme fonctionne sur un principe de réduction de l'espace de solution très simple. Autrement dit, réduisez le cube à un état dans lequel un sous-ensemble de torsions n'est pas nécessaire pour le résoudre, réduisez-le à un espace de solution plus petit, puis résolvez le reste en utilisant uniquement les quelques torsions restantes.
Thistlethwaite suggéré à l'origine
<L,R,F,B,U,D>
→<L,R,F,B,U2,D2>
→<L,R,F2,B2,U2,D2>
→<L2,R2,F2,B2,U2,D2>
. Cependant, étant donné le format d'entrée, je pense qu'il est plus facile de réduire d'abord à<L,R,F2,B2,U,D>
(pas de quart de tourF
ouB
), et ensuite<L2,R2,F2,B2,U,D>
avant d'atteindre l'état de demi-tour. Au lieu d’expliquer exactement pourquoi, je pense que ce sera évident après la définition des critères pour chaque État.<L,R,F,B,U,D>
⇒<L,R,F2,B2,U,D>
Pour éliminer
F
etB
quart de tour, seules les arêtes doivent être correctement orientées. Gilles Roux a une très bonne explication sur son site de ce qu'est une orientation "correcte" et "incorrecte", je vais donc lui laisser l'explication. Mais au fond, (ce qui est la raison pour laquelle ce format d'entrée est donc propice auF
etB
élimination), un Cubie de bord est orienté correctement si elle correspond à l'expression rationnelle suivante:[^RL][^UD]
. Une orientation correcte est généralement indiquée avec un0
et incorrect avec1
. FondamentalementU
etD
autocollants peuvent ne pas apparaître sur lesR
ouL
faces, ou sur les bords des toutU
ouD
bord petits cubes, ou ils ne peuvent pas être déplacés en place sans avoir besoin d' unF
ouB
quart de tour.<L,R,F2,B2,U,D>
⇒<L2,R2,F2,B2,U,D>
Deux critères ici. Tout d' abord, tous les coins doivent être orientés correctement, et d' autre part, chacun des pour petits cubes de couche du milieu (
FR
,FL
,BR
,BL
) doit être quelque part dans la couche intermédiaire. Une orientation de coin est très simplement définie en fonction du format d'entrée: la position du premierU
ouD
. Par exemple,URB
a une orientation0
(correctement orientée),LDF
a une orientation1
etLFU
a une orientation2
.<L2,R2,F2,B2,U,D>
⇒<L2,R2,F2,B2,U2,D2>
Les critères sont les suivants: chaque face ne peut contenir que des autocollants collés sur sa face ou directement sur la face opposée. Par exemple, sur le
U
visage , il ne peut êtreU
etD
autocollants, sur leR
visage , il ne peut y avoirR
etL
autocollants, sur leF
visage , il peut seulement êtreF
etB
autocollants, etc. La façon d' y parvenir est plus facile de vérifier si chaque pièce de bord est en sa "tranche" et chaque coin dans son "orbite". De plus, il faut faire attention à la parité des bords. Bien que, si vous ne vérifiez que la parité d'angle, la parité de bord est également garantie, et inversement.Comment les rebondissements affectent l'orientation
U
et lesD
torsions n’affectent ni l’orientation des bords, ni l’angle des angles. Les pièces peuvent être échangées directement sans mettre à jour le vecteur d’orientation.R
et lesL
torsions n’affectent pas l’orientation des bords, mais l’orientation des coins. Selon la façon dont vous définissez votre cycle, le changement d'orientation des coins sera soit modulaire,+1, +2, +1, +2
soit+2, +1, +2, +1
modulaire3
. Notez queR2
etL2
torsions ne touchent pas l'orientation du coin, comme+1+2
est égal à zéro modulo3
, comme+2+1
.F
etB
affecte à la fois les orientations des bords et les orientations des coins. Les orientations des bords deviennent+1, +1, +1, +1
(mod 2) et les orientations des coins sont les mêmes que pourR
etL
. Notez queF2
etB2
affectent ni les orientations de bord, ni les orientations d'angle.la source
<L,R,F,B,U,D>
-><L2,R2,F2,B2,U,D>
-><I>
. La résolution d'un cube nécessite au maximum 29 torsions (au lieu de 52 pour celles de Thistlethwaite), mais elle nécessite également de très grandes tables de consultation, ce qui ne serait pas pratique pour générer "à la volée".Ruby, 742 caractères
Le code ruby ci-dessus n'est pas encore complètement joué au golf. Il reste encore des possibilités d’améliorer le code (mais c’est déjà suffisant en tant que démarreur).
Il résout le cube couche par couche mais n'utilise aucun algorithme spécifique, mais effectue des séquences aléatoires de déplacements jusqu'à la résolution du cube.
En raison de la nature probabiliste, la résolution du cube peut prendre parfois plus de 5 secondes et, dans de rares cas, plus de 1 000 déplacements sont nécessaires.
Exemple de sortie (pour l'entrée 'RU LF UB DR DL BL UL FU BD RF BR FD LDF LBD FUL RFD UFR RDB UBL RBU') est de 757 mouvements:
Il est possible de réduire considérablement le nombre de mouvements si les mêmes mouvements sont regroupés. Par conséquent, on peut remplacer la sortie comme
la source
FU FR RU BR DB LD LU LB LF RD DF BU FRU BUR FDR DLB DFL LUB FUL DBR
U1 U1 U1
en une seuleU3
?