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;
}
}
}