Ta tâche
.. est de faire ce que Brian Fantana n'a apparemment pas pu faire, et de résoudre le Rubik's Cube 2x2x2.
La disposition
- - A B - - - -
- - C D - - - -
E F G H I J K L
M N O P Q R S T
- - U V - - - -
- - W X - - - -
Et vous sera remis via stdin ou la ligne de commande (votre choix - veuillez préciser dans votre réponse) au format:
ABCDEFGHIJKLMNOPQRSTUVWX
Notez que AD constitue la face U (vers le haut), EFMN constitue la face L (gauche), GHOP constitue la face F (avant), IJQR constitue la face R (droite), KLST constitue la Face B (arrière) et UX composent la face D (bas).
Il y aura six caractères uniques représentant chaque couleur, mais ils peuvent varier, alors préparez-vous à toute combinaison de 6 caractères ascii à utiliser pour chaque couleur.
Caractéristiques
- Votre code doit générer une solution utilisant uniquement les faces droite (R), supérieure (U) et avant (F), et doit utiliser la notation standard: R, R ', R2, U, U', U2, F, F », F2. Vous pouvez trouver plus d'informations ici . La restriction du sous-ensemble RUF est standard pour le cube 2x2 (Astuce: traiter le coin inférieur arrière-gauche comme une base fixe à partir de laquelle travailler).
- Votre code doit être capable de résoudre toutes les permutations possibles du cube de poche.
- Chaque solution devrait prendre moins de 30 secondes.
- Chaque solution doit être inférieure à 30 mouvements.
- Un bonus de -20% sera accordé pour les solutions fournissant toujours des réponses à moins de 20 coups (veuillez en faire la publicité dans votre réponse afin que je puisse en faire une vérification approfondie)
- Un bonus de -50% sera accordé pour le code qui fournit toujours une solution optimale. - Encore une fois, veuillez annoncer dans votre réponse
- Les solutions ne doivent pas contenir deux mouvements consécutifs sur la même face, car ils peuvent être facilement combinés en un seul mouvement.
- Les solutions peuvent éventuellement contenir un seul espace - et seulement un seul espace - entre chaque mouvement.
- La séquence de solution entière, si nécessaire, peut être contenue dans une paire de parenthèses, guillemets, accolades, crochets ou carets, mais aucune autre sortie étrangère n'est autorisée.
- Veuillez fournir une version brièvement commentée de votre code ou une explication approfondie de votre code.
- Pas d'utilisation de fichiers externes. Cela inclut Internet, les tableaux de données et les bibliothèques / packages conçus pour ce type de problème.
- Le code le plus court par nombre d'octets gagne.
- Gagnant choisi mercredi (30 juillet 2014).
code-golf
puzzle-solver
permutations
rubiks-cube
Kyle McCormick
la source
la source
Réponses:
Python 2.7: 544 octets -50% = 272 octets **
Stackexchange remplace les onglets par plusieurs espaces blancs. Si technique cette version compte 549 octets. Remplacez simplement les deux premiers espaces des lignes 6 à 10 par un tabulateur.
Idée derrière mon programme: Ma première idée a été une première recherche de souffle. Mais cela a pris trop de temps. Environ 2 minutes pour une course difficile (11 mouvements optimaux). J'ai donc décidé d'aborder le problème des deux côtés. J'utilise deux ensembles. Je génère séquentiellement tous les états avec la distance 1,2,3, ... au brouillage et les sauvegarde dans set1, et en même temps tous les états avec la distance 1,2,3, ... à l'état résolu et les sauvegarde dans set2. La première fois qu'un état est dans les deux ensembles, nous avons trouvé la solution.
Pour cela, j'ai besoin des couleurs du cube résolu, qui ne sont pas connues. Les caractères 13, 20 et 23 définissent la couleur gauche, arrière et bas. Mais ces 3 couleurs suffisent pour représenter le cube. Je remplace simplement les 3 autres couleurs par des espaces blancs et je peux représenter mon état résolu comme «____ll____bbll____dddd».
Oh, et pour raccourcir les permutations, j'ai utilisé une idée de /codegolf//a/34651/29577
Version non golfée:
Je suis assez content du résultat, car je suis assez nouveau sur Python. Ceci est l'un de mes premiers programmes python.
édition: six mois plus tard: 427 - 50% = 213,5
J'ai un peu plus d'expérience en Python et en golf. J'ai donc révisé mon code d'origine et j'ai pu enregistrer plus de 100 caractères.
J'utilise essentiellement la même approche. Le plus grand changement est que je ne définis plus de fonction. Au lieu de
Je peux faire
J'ai aussi changé un peu le mouvement lamda. D'abord raccourci, puis intégré directement le code, car l'appel de fonction n'apparaît qu'une seule fois.
Je garde pour chaque état une liste de nombres entre 0 et 11, pour représenter les coups, au lieu d'une chaîne contenant les coups. Les nombres sont convertis à la toute fin.
J'ai également combiné les deux boucles for
'for k in r(3):for j in r(3):
en une seulefor y in r(12)
. Par conséquent, je dois également faire les mouvementsU4, R4, F4
. Bien sûr, un tel mouvement n'apparaît pas dans la solution la plus courte, donc ça" 2'"[x%4]
marche. (Six % 4 == 3
, il y aurait une exception d'index hors plage)C'est aussi un peu plus rapide, car je cherche l'entrée dans le deuxième set plus tôt. Environ 0,5 seconde pour une solution à 11 mouvements.
la source
C, 366 - Bonus optimal de 50% = 183
En utilisant la récursivité, le programme recherche dans un arbre de jusqu'à 11 mouvements de profondeur (la longueur maximale d'un soluton optimal selon http://en.wikipedia.org/wiki/Pocket_Cube et la page mentionnée ci-dessous) et quand il trouve une solution il l'imprime (jusqu'à 22 caractères de long, suivi par l'argument de la fonction
m
.) L'ordre utilisé est une sorte d'ordre de dictionnaire, où toutes les routes commençant U, U2, U 'sont recherchées avant toute route commençant R ou F. Ainsi, il ne trouve pas nécessairement la solution optimale en premier.Lorsqu'une solution est imprimée,
r
est égal àm
ce qui garantit que seules des solutions égales ou plus courtes seront imprimées par la suite. La miser=m-2
coûte 2 caractères supplémentaires mais garantit qu'une seule solution de chaque longueur trouvée (jusqu'à optimale) est imprimée. Si vous souhaitez qu'il affiche UNIQUEMENT la solution optimale, la meilleure solution trouvée jusqu'à présent doit être stockée dans une variable et la solution optimale imprimée à la fin du programme (cela coûterait environ 15 caractères supplémentaires.)l'entrée est lue dans le tableau à
c[]
partir de l'index 64. Ceci est nécessaire pour utiliser des caractères alphabétiques dans le mobile. Les symboles à@
traversW
sont utilisés à la place de A à X par la question, car il est nécessaire de commencer sur un nombre pair pour faire fonctionner le test des solutions.c['Z']
est également utilisé pour le stockage temporaire, car pour effectuer une rotation quadruple, un total de 5 affectations est nécessaire. Étant donné que la première partie dec[]
n'est pas utilisée, elle est disponible pour stocker la solution (qui se termine par un octet zéro, comme toutes les chaînes C.)for(i..)
passe par une séquence de 4 quarts de tour du visage spécifié parn
.Le premier
for(j..)
effectue l'échange réel selon le tableaut[]
.Pour tester si le cube est résolu, il suffit de vérifier les quatre faces latérales.Les pièces URF et DFR peuvent être distinguées même avec les autocollants U et D retirés, car une pièce lit XRF dans le sens horaire et l'autre XFR. Si les deux pièces sont échangées de sorte que U s'affiche sur la face inférieure et vice versa, la couleur F apparaîtra sur la face droite et vice versa.
Le second
for(j..)
compte le nombre de décalages sur les quatre faces latérales. Par exemple, pour la face avant, il compare G & O, H & P et G & H (deux fois). Sie
== 0, le cube est résolu. Sie
<9 oue
<13, il pourrait être possible de résoudre le cube dans le prochain mouvement ou 2 mouvements respectivement. Sinon, il n'est certainement pas possible de résoudre le cube dans ce nombre de mouvements. Afin de gagner du temps, cette heuristique est utilisée pour tailler l'arbre de recherche et éviter de perdre du temps sur plusieurs de ces branches de profondeur 10 ou 11 qui seront infructueuses. Exprimé sous forme de formule, cela deviente<45-m*2
.Code non golfé
Performance
Le programme a été testé avec les modèles 1 à 13 sur http://www.jaapsch.net/puzzles/cube2.htm
Les résultats suivants donnent le timing sur ma machine pour trouver TOUTES les solutions optimales (pour les curieux.) Aussi pour les positions plus complexes, le timing est donné pour la modification de 2 octets mentionnée ci-dessus qui ne trouve qu'une seule solution optimale. Pour cela, des temporisations sont données à la fois pour trouver la première solution et pour que le programme se termine. Les solutions proposées (qui sont généralement différentes des solutions obtenues en inversant les générateurs sur la page liée) ont été vérifiées avec un simulateur de cube en ligne.
la source