En faisant tourner mon cube de Rubik sans rien faire , mon fils a remarqué qu'il revenait constamment à l'état résolu. Je suis à peu près sûr qu'il pensait qu'il s'agissait d'une sorte de magie vaudou au début, mais je lui ai expliqué que si vous répétez la même séquence de mouvements, elle reviendra toujours à son état d'origine. Finalement.
Bien sûr, étant un enfant, il devait l'essayer lui-même et choisir une séquence "aléatoire" qui, selon lui, serait délicate. Il a perdu le fil après une dizaine de répétitions et m'a demandé combien de fois il devrait le répéter. Ne sachant pas la séquence qu'il utilisait, je lui ai dit que je ne le savais pas, mais que nous pourrions écrire un programme pour le découvrir.
C’est là que vous intervenez. Bien sûr, je pourrais simplement préparer quelque chose, mais il aimerait le taper lui-même. Il n’est pas encore très rapide comme dactylographe, alors j’ai besoin du programme le plus court possible .
Objectif
Avec une séquence de tours, affichez le moins de fois possible pour que le cube revienne à son état d'origine. C'est le code de golf, donc le moins d'octets gagne. Vous pouvez écrire un programme ou une fonction et appliquer toutes les autres valeurs par défaut habituelles.
Contribution
L'entrée est une séquence de mouvements, pris comme une chaîne, une liste ou tout autre format adapté à votre langue. N'hésitez pas à utiliser un séparateur (ou non) entre les déplacements si vous êtes sous forme de chaîne.
Il y a six mouvements "de base" qui doivent être pris en compte, ainsi que leurs inverses:
R - Turn the right face clockwise
L - Turn the left face clockwise
U - Turn the up (top) face clockwise
D - Turn the down (bottom) face clockwise
F - Turn the front face clockwise
B - Turn the back face clockwise
Les inverses sont représentés en ajoutant une marque principale '
après la lettre. Cela indique que vous tournez cette face dans le sens inverse des aiguilles d'une montre. Vous devez donc F'
tourner la face avant dans le sens contraire des aiguilles d'une montre F F'
pour rétablir immédiatement l'état d'origine.
Pour les intéressés, ce défi utilise un ensemble limité de notation Singmaster . Ruwix propose de jolies animations si vous souhaitez le voir en action.
Sortie
La sortie est simplement le nombre minimum de fois que la séquence d'entrée doit être effectuée.
Exemples
Input Output
FF' -> 1
R -> 4
RUR'U' -> 6
LLUUFFUURRUU -> 12
LUFFRDRBF -> 56
LF -> 105
UFFR'DBBRL' -> 120
FRBL -> 315
Voici un solveur (assez naïf) avec lequel comparer vos réponses, écrit en Java. Il accepte également les 2
coups doubles (le quatrième cas est équivalent à L2U2F2U2R2U2
).
import java.util.ArrayList;
import java.util.List;
public class CycleCounter{
public static void main(String[] args){
int[] cube = new int[54];
for(int i=0;i<54;i++)
cube[i] = i;
String test = args.length > 0 ? args[0] : "RUR'U'";
List<Rotation> steps = parse(test);
System.out.println(steps.toString());
int count = 0;
do{
for(Rotation step : steps)
cube = step.getRotated(cube);
count++;
}while(!isSorted(cube));
System.out.println("Cycle length for " + test + " is " + count);
}
static List<Rotation> parse(String in){
List<Rotation> steps = new ArrayList<Rotation>();
for(char c : in.toUpperCase().toCharArray())
switch(c){
case 'R':steps.add(Rotation.R);break;
case 'L':steps.add(Rotation.L);break;
case 'U':steps.add(Rotation.U);break;
case 'D':steps.add(Rotation.D);break;
case 'F':steps.add(Rotation.F);break;
case 'B':steps.add(Rotation.B);break;
case '\'':
steps.add(steps.get(steps.size()-1));
case '2':
steps.add(steps.get(steps.size()-1));
break;
}
return steps;
}
static boolean isSorted(int[] in){for(int i=0;i<in.length-1;i++)if(in[i]>in[i+1])return false;return true;}
enum Rotation{
R(new int[]{-1,-1,42,-1,-1,39,-1,-1,36, -1,-1,2,-1,-1,5,-1,-1,8, 20,23,26,19,-1,25,18,21,24, -1,-1,11,-1,-1,14,-1,-1,17, 35,-1,-1,32,-1,-1,29,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1}),
L(new int[]{9,-1,-1,12,-1,-1,15,-1,-1, 27,-1,-1,30,-1,-1,33,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1, 44,-1,-1,41,-1,-1,38,-1,-1, -1,-1,6,-1,-1,3,-1,-1,0, 47,50,53,46,-1,52,45,48,51}),
U(new int[]{2,5,8,1,-1,7,0,3,6, 45,46,47,-1,-1,-1,-1,-1,-1, 9,10,11,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1, 18,19,20,-1,-1,-1,-1,-1,-1, 36,37,38,-1,-1,-1,-1,-1,-1}),
D(new int[]{-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,24,25,26, -1,-1,-1,-1,-1,-1,42,43,44, 29,32,35,28,-1,34,27,30,33, -1,-1,-1,-1,-1,-1,51,52,53, -1,-1,-1,-1,-1,-1,15,16,17}),
F(new int[]{-1,-1,-1,-1,-1,-1,18,21,24, 11,14,17,10,-1,16,9,12,15, 29,-1,-1,28,-1,-1,27,-1,-1, 47,50,53,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,8,-1,-1,7,-1,-1,6}),
B(new int[]{51,48,45,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,0,-1,-1,1,-1,-1,2, -1,-1,-1,-1,-1,-1,26,23,20, 38,41,44,37,-1,43,36,39,42, 33,-1,-1,34,-1,-1,35,-1,-1});
private final int[] moves;
Rotation(int[] moves){
this.moves = moves;
}
public int[] getRotated(int[] cube){
int[] newCube = new int[54];
for(int i=0;i<54;i++)
if(moves[i]<0)
newCube[i] = cube[i];
else
newCube[moves[i]] = cube[i];
return newCube;
}
}
}
Réponses:
Pyth,
6663 octetsEssayez-le en ligne: Démonstration ou Suite de tests . Notez que le programme est un peu lent et que le compilateur en ligne ne peut pas calculer la réponse
RU2D'BD'
. Mais soyez assuré qu'il peut le calculer sur mon ordinateur portable en environ 12 secondes.Le programme (accidentellement) accepte également les
2
doubles mouvements.Explication complète:
Brouillage d'analyse:
Je traiterai d’abord des notes principales
'
dans les chaînes de saisie. Je remplace simplement ceux-ci par3
et la longueur de décodage de cette chaîne. Comme le format de décodage de Pyth nécessite le nombre devant le caractère, je inverse la chaîne au préalable._r_Xz\'\39
. Alors après, je l'inverse.Décrivez l'état du cube résolu:
=Z"UDLRFB
assigne la chaîne avec tous les 6 coups àZ
.Nous pouvons décrire un état de cube en décrivant l'emplacement de chaque morceau de cube. Par exemple, nous pouvons dire que le bord, qui devrait être à UL (haut-gauche) est actuellement à FR (avant-droit). Pour cela , je dois générer toutes les pièces du cube résolu:
f!s}RTcZ2yZ
.yZ
génère tous les sous-ensembles possibles de"UDLRFB"
. Cela génère évidemment aussi le sous-ensemble"UDLRFB"
et le sous-ensemble"UD"
. Le premier n'a aucun sens, car aucune pièce n'est visible des 6 côtés, et le second n'a aucun sens, puisqu'il n'y a pas de bord, visible du haut et du bas. . Par conséquent, je supprime tous les sous-ensembles contenant la sous-séquence"UD"
,"LR"
ou"FB"
. Cela me donne les 27 pièces suivantes:Cela inclut également la chaîne vide et les six chaînes d'une lettre. Nous pourrions les interpréter comme la pièce au milieu du cube et les 6 pièces centrales. Évidemment, ils ne sont pas nécessaires (puisqu'ils ne bougent pas), mais je les garde.
Faire quelques mouvements:
Je vais faire quelques traductions de chaîne pour effectuer un mouvement. Pour visualiser l’idée, regardez le coin dans
URF
. Qu'advient-il de cela quand je fais unR
déménagement? L'autocollant sur leU
visage se déplace vers leB
visage, l'autocollantF
sur leU
visage et l'autocollant sur leR
visage reste sur leR
visage. Nous pouvons dire que la pièce àURF
se déplace à la positionBRU
. Ce modèle est vrai pour toutes les pièces du côté droit. Chaque sticker qui est sur leF
visage se déplace vers leU
visage quand unR
mouvement est effectué, chaque autocollant qui est sur leU
visage se déplace vers leB
visage, chaque autocollant sur lesB
mouvements àD
et chaque autocollant surD
se déplaceF
. Nous pouvons décoder les changements d'unR
mouvement en tant queFUBD
.Le code suivant génère tous les 6 codes nécessaires:
Et nous effectuons un déplacement
H
vers l'état du cubeG
comme suit:Comptez le nombre de répétitions:
Le reste est à peu près trivial. J'effectue simplement le brouillage d'entrée dans le cube résolu encore et encore jusqu'à atteindre une position que j'avais précédemment visitée.
la source
GAP,
792 783 782749650 OctetsCela à l'air de marcher. Si quelque chose ne va pas, faites le moi savoir.
Merci à @Lynn pour m'avoir suggéré de décomposer certains des mouvements primitifs.
Merci à @Neil d’avoir suggéré cela au lieu de l’
Inverse(X)
utiliserX^3
.Exemple d'utilisation:
f("R");
Voici le code non-golfé avec quelques explications
la source
45
par5
dans vos permutations et économiser trois octets.A:=R*L*L*L*F*F*B*B*R*L*L*L;D:=A*U*A;
est plus court que votre définition deD
(mais je ne peux pas le tester ...)^-1
pour les inverses, BTW?Mathematica,
413401 octetsDes explications
Un Rubik's Cube est composé de 20 cubes mobiles (8 coins, 12 bords). Un numéro peut être attribué à chaque casier:
coins :
bords :
Notez que lorsque le cube est tordu, les cubes ne sont généralement plus sur leurs positions de départ. Par exemple, lorsque cela
R
est fait, le groupe1
passe d'UFR
une nouvelle position à une autreUBR
.Dans cette notation, un virage à 90 degrés peut être décrit par 8 mouvements de cubies. Par exemple,
R
est décrit parÉtant donné que chaque casier a une position de départ unique, chaque position a un casier de départ unique. C'est-à-dire que la règle
UFR->UBR
est juste1->2
(signifie que celaR
prend le cube sur la position de départ de cubie1
à la position de départ de cubie2
). Ainsi,R
peut être simplifié suite à un cyclePour résoudre complètement un cube de Rubik, nous devons également aligner les cubes sur leurs orientations de départ correspondantes. Les faces d’un cube sont peintes de différentes couleurs, le schéma que j’utilise souvent pour résoudre des cubes est
Lorsque nous analysons les orientations des coins, les couleurs autres que le jaune ou le blanc sont ignorées, et le jaune et le blanc sont considérés comme la même couleur.
Supposons que cubie
1
soit sur sa position de départUFR
, la facette jaune peut être alignée sur trois faces différentes. Nous utilisons un entier pour représenter ces cas,Supposons que cubie
1
soit activéDFL
, ses trois orientations possibles sontLorsque nous analysons les orientations des bords, le rouge et l’orange sont ignorés, et le jaune et le blanc ne sont ignorés que si le bord a une facette verte ou bleue.
Supposons que cubie
10
soit sur sa position de départUR
, la facette verte peut être alignée sur deux faces différentes. Ses deux orientations possibles sontSupposons que cubie
10
soit activéDF
, ses deux orientations possibles sontUn tableau est utilisé pour stocker l'état d'un cube. L'état de départ d'un cube est
ce qui signifie que tous les cubes sont sur leur position de départ avec une orientation correcte.
Après
R
, l'état du cube devientce qui signifie que cubie
5
est maintenant sur position1
(UFR
) avec orientation2
, cubie1
est maintenant sur position2
(UBR
) avec orientation1
, cubie3
est maintenant toujours sur position3
(UBL
) avec orientation0
, et ainsi de suite.Cas de test
la source
Haskell, 252 octets
Échantillons:
L'observation clé ici est qu'il est plus simple de modéliser le cube de Rubik sous la forme d'une grille de points 5 × 5 × 5 plutôt que d'une grille 3 × 3 × 3 de cubies orientés. Les cubes d'angle deviennent des cubes de 2 × 2 × 2 points, les cubes de bords deviennent des carrés de 2 × 2 × 1 points et des tranches de 5 × 5 × 2 en rotation.
la source
c:"'"
parc:_
sauve deux octets._
correspond également à la liste vide.Ruby, 225 octets
Similaire à la réponse d'Anders Kaseorg et inspiré par la réponse de Jan Dvorak à une question précédente.
Cependant, contrairement à ces réponses, je n'ai pas besoin de 125 cubes. J'utilise un cube en rubik de 27 cubes, mais de dimensions rectangulaires. Dans l'état résolu, les coins sont à
+/-1,+/-4,+/-16
.Je génère un tableau de 64 cubies, chacune avec un centre choisi
x=[-1,0,1,2], y=[-4,0,4,8], z=[-16-0,16,32]
. Les cubes avec des coordonnées de 2, 8 et 32 ne sont pas nécessaires, mais ils ne font pas de mal, ils sont donc laissés à l'intérieur pour des raisons de golf. Le fait que les cubies aient une longueur, une largeur et une profondeur différentes (1,4,16) signifie qu'il est facile de détecter s'ils se trouvent au bon endroit mais dans la mauvaise orientation.Chaque casier est suivi au fur et à mesure qu’il est déplacé par les équipes. Si la coordonnée d'un cube dans l'axe correspondant à la face (multipliée par
e=-1
pour U, F, R oue=1
pour D, B, L) est positive, elle sera pivotée en échangeant les coordonnées dans les 2 autres axes et en appliquant un signe approprié changer à l'une des coordonnées. Ceci est contrôlé en multipliant pare*d
.La séquence d'entrée est balayée dans l'ordre inverse. Cela ne fait aucune différence, tant que les rotations "normales" sont effectuées dans le sens inverse des aiguilles d'une montre et non dans le sens des aiguilles d'une montre. La raison en est que, si un
'
symbole est trouvé, la valeur ded
peut être modifiée de 1 à -1 afin de provoquer la rotation de la face suivante dans le sens opposé.Programme non testé
la source
Python 2, 343 octets
L'entrée est prise de stdin.
La séquence de torsions donnée est exécutée de manière répétée sur un cube virtuel jusqu'à ce qu'il revienne à l'état résolu. L'état du cube est stocké en tant que vecteur d'orientation et vecteur de permutation, tous deux de longueur 20.
Les orientations sont définies de manière quelque peu arbitraire: un groupe de bord est correctement orienté s'il peut être déplacé sans invoquer un quart de tour R ou L. L'orientation des coins est considérée par rapport aux faces F et B.
Exemple d'utilisation
Démonstration en ligne et suite de tests .
la source
Clojure, 359 octets
Cela pourrait être mon deuxième plus long codegolf. Se rendant compte que je pouvais laisser tomber zéros de vecteurs
A
àF
m'a rendu très heureux: DMoins joué au golf:
Ceci implémente simplement des rotations 3D de sous-ensembles sélectionnés de
5 x 5 x 5
cube. À l'origine, j'allais l'utiliser3 x 3 x 3
et il m'a fallu un certain temps pour comprendre pourquoi mes résultats n'étaient pas corrects. Bons cas de test! Certains octets supplémentaires pour l' encodage poing"RUR'U'"
comme"RURRRUUU"
.la source
Cubiquement ,
9 à6 octetsEssayez-le en ligne! (Non actif jusqu'à ce que Dennis mette à jour l'interprète TIO Cubiquement)
Explication:
Cette langue dominera tous les défis rubiks-cube >: D
la source
-7
signifiait soustraire sept pas ajouter un en colère shakes walkerNettoyer , 255 octets
Dérivée séparément de la réponse presque identique de Haskell en réponse à cette question qui était fermée en double lorsqu'elle était presque terminée, j'ai donc posté la réponse ici.
Essayez-le en ligne!
la source