ルービックキューブを無造作にひねりながら、息子は解かれた状態に戻っていることに気付きました。彼はこれが最初はブードゥー教の魔法だと思っていたと思いますが、同じ動きのシーケンスを繰り返し続けると、常に元の状態に戻ると説明しました。最終的に。
もちろん、子供の頃、彼は自分で試してみて、トリッキーだと思った「ランダムな」シーケンスを選択する必要がありました。彼は10回ほど繰り返した後にトラックを失い、何回それを繰り返さなければならないかを尋ねました。彼が使用しているシーケンスを知らなかったので、私は知らなかったが、調べるためのプログラムを書くことができると彼に言った。
ここがあなたの出番です。もちろん、私はただ何かを上げることができますが、彼は自分でそれを入力したいと思います。彼はまだ非常に高速なタイピストではないので、可能な限り短いプログラムが必要です。
目的
ターンのシーケンスが与えられた場合、キューブを元の状態に戻すために実行する必要がある最小回数を出力します。これはコードゴルフなので、最小バイトが勝ちます。プログラムまたは関数を作成でき、他のすべての通常のデフォルトが適用されます。
入力
入力は、文字列、リスト、または言語に適した他の形式として取得される一連の移動です。文字列形式の場合は、移動の間にセパレータを自由に使用できます(または使用しません)。
考慮に入れなければならない6つの「基本的な」動きとその逆があります。
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
逆は'
、文字の後にプライムマークを追加することによって表されます。これは、その面を反時計回りに回すことを示しているためF'
、前面を反時計回りに回し、すぐF F'
に元の状態に戻します。
興味のある方のために、この課題はSingmaster Notationの限られたセットを使用しています。Ruwixの動作を確認したい場合は、いくつかの素晴らしいアニメーションがあります。
出力
出力は、単純に入力シーケンスを実行する必要がある最小回数です。
例
Input Output
FF' -> 1
R -> 4
RUR'U' -> 6
LLUUFFUURRUU -> 12
LUFFRDRBF -> 56
LF -> 105
UFFR'DBBRL' -> 120
FRBL -> 315
Javaで記述された、あなたの答えを比較する(非常に素朴な)ソルバーを次に示します。また2
、ダブルムーブも受け入れます(4番目のケースはに相当します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;
}
}
}