Während mein Sohn müßig den Zauberwürfel herumdrehte, bemerkte er, dass er immer wieder in den gelösten Zustand zurückkehrte. Ich bin mir ziemlich sicher, dass er anfangs dachte, dies sei eine Art Voodoo-Magie, aber ich erklärte, dass, wenn Sie dieselbe Abfolge von Zügen wiederholen, diese immer in ihren ursprünglichen Zustand zurückkehren wird. Schließlich.
Natürlich musste er es als Kind selbst ausprobieren und eine "zufällige" Sequenz auswählen, die er für schwierig hielt. Nach etwa zehn Wiederholungen verlor er den Überblick und fragte mich, wie oft er es wiederholen müsse. Da ich nicht wusste, welche Sequenz er benutzte, sagte ich ihm, dass ich es nicht wüsste, aber dass wir ein Programm schreiben könnten, um es herauszufinden.
Hier kommst du rein. Natürlich könnte ich einfach etwas zaubern, aber er würde es gerne selbst eintippen. Er ist allerdings noch kein sehr schneller Typist, deshalb brauche ich das kürzestmögliche Programm .
Zielsetzung
Geben Sie in einer vorgegebenen Abfolge von Umdrehungen so oft wie möglich aus, um den Würfel wieder in den ursprünglichen Zustand zu versetzen. Dies ist Codegolf, also gewinnen die wenigsten Bytes. Sie können ein Programm oder eine Funktion schreiben, und es gelten alle anderen üblichen Standardeinstellungen.
Eingang
Die Eingabe ist eine Folge von Zügen, die als Zeichenfolge, Liste oder in einem anderen Format für Ihre Sprache verwendet werden. Fühlen Sie sich frei, ein Trennzeichen (oder nicht) zwischen Zügen zu verwenden, wenn es sich um eine Zeichenfolge handelt.
Es gibt sechs "grundlegende" Züge, die zusammen mit ihren Inversen berücksichtigt werden müssen:
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
Die Umkehrungen werden durch das Hinzufügen eines Strichs '
nach dem Buchstaben dargestellt. Dies zeigt an, dass Sie dieses Gesicht gegen den Uhrzeigersinn drehen, also F'
das vordere Gesicht gegen den Uhrzeigersinn drehen und F F'
es sofort in den ursprünglichen Zustand zurückversetzen würden.
Für die Interessenten wird bei dieser Herausforderung eine begrenzte Anzahl von Singmaster-Notationen verwendet . Ruwix hat einige nette Animationen, wenn Sie es in Aktion sehen möchten .
Ausgabe
Die Ausgabe ist einfach die Mindestanzahl, mit der die Eingabesequenz ausgeführt werden muss.
Beispiele
Input Output
FF' -> 1
R -> 4
RUR'U' -> 6
LLUUFFUURRUU -> 12
LUFFRDRBF -> 56
LF -> 105
UFFR'DBBRL' -> 120
FRBL -> 315
Hier ist ein (ziemlich naiver) Löser, mit dem Sie Ihre in Java geschriebenen Antworten vergleichen können. Es werden auch 2
Doppelzüge akzeptiert (der vierte Fall ist also gleichbedeutend mit 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;
}
}
}