ルービックとのサイクリング


43

ルービックキューブを無造作にひねりながら、息子は解かれた状態に戻っていることに気付きました。彼はこれが最初はブードゥー教の魔法だと思っていたと思いますが、同じ動きのシーケンスを繰り返し続けると、常に元の状態に戻ると説明しました。最終的に。

もちろん、子供の頃、彼は自分で試してみて、トリッキーだと思った「ランダムな」シーケンスを選択する必要がありました。彼は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;
        }
    }
}

「時計回り」とは、「直面しているときは時計回り」という意味ですか?
msh210

@ msh210正しい。
ジオビット

7
物足りな点では、十分な最小数が必要であることを明確にする必要があると思います。そうでなければ私はちょうど出力グループの大きさとは...ラグランジュの定理を引用することができ
ピーター・テイラー

2
@PeterTaylor Pedantryが受け入れられました。
ジオビット

4
私はありシャッフル内の溶液を500ポイントの恩恵を提供します。まだ確かじゃない。
リルトシアスト

回答:


16

Pyth、66 63バイト

l.uum.rW}Hdd@_sm_B.iFP.>c3Zk3xZHG_r_Xz\'\39Nf!s}RTcZ2y=Z"UDLRFB

オンラインで試してみてください:デモンストレーションまたはテストスイート。プログラムがやや遅く、オンラインコンパイラがの答えを計算できないことに注意してくださいRU2D'BD'。しかし、ラップトップで約12秒で計算できることを確認してください。

プログラムは(偶然)2ダブルムーブも受け入れます。

完全な説明:

スクランブルの解析:

最初に'、入力文字列のプライムマークを扱います。これらを単に置き換え、3この文字列をランレングスデコードします。Pythのデコード形式ではcharの前に数字が必要なので、事前に文字列を逆にします。_r_Xz\'\39。そのため、その後、逆に戻します。

解決されたキューブの状態を説明します。

=Z"UDLRFBは、6つの移動すべてを含む文字列をに割り当てますZ

各キューブピースの位置を記述することにより、キューブの状態を記述することができます。たとえば、UL(Up-Left)にあるはずのエッジは、現在FR(Front-Right)にあると言えます。このために、解決されたキューブのすべてのピースを生成する必要がありますf!s}RTcZ2yZyZのすべての可能なサブセットを生成します"UDLRFB"。これは明らかにサブセット"UDLRFB"とサブセットも生成し"UD"ます。最初の1つは意味がありません。6面すべてから見えるピースがないためです。2つ目は、上下から見えるエッジピースがないため意味がありません。 。したがって、私は、サブシーケンスを含むすべてのサブセットを、削除"UD""LR"または"FB"。これにより、次の27個が得られます。

'', 'U', 'D', 'L', 'R', 'F', 'B', 'UL', 'UR', 'UF', 'UB', 'DL', 'DR', 'DF', 'DB', 
'LF', 'LB', 'RF', 'RB', 'ULF', 'ULB', 'URF', 'URB', 'DLF', 'DLB', 'DRF', 'DRB'

これには、空の文字列と6つの1文字の文字列すべても含まれます。それらを立方体の中央の部分と6つの中央の部分として解釈できます。明らかに(移動しないので)必要ありませんが、私はそれらを保持します。

いくつかの動きをする:

移動を実行するために、文字列の翻訳をいくつか行います。アイデアを視覚化するには、のコーナーピースをご覧くださいURF。私がやると何が、それはどうR動きますか?上のステッカーUの顔が動くB顔、ステッカーFに移動U顔とのステッカーRの顔の滞在R顔。ピースURFがの位置に移動すると言うことができますBRU。このパターンは、右側のすべてのピースに当てはまります。上にあるすべてのステッカーFに顔を移動URの上にある移動が行われ、すべてのステッカーUに顔が動くB顔、上のすべてのステッカーBに移動Dし、上のすべてのステッカーDに移動FR動きの変化をとしてデコードできFUBDます。

次のコードは、6つの必要なコードをすべて生成します。

_sm_B.iFP.>c3Zk3
['BRFL', 'LFRB', 'DBUF', 'FUBD', 'RDLU', 'ULDR']
    ^       ^       ^       ^       ^       ^
 U move  D move  L move  R move  F move  B move

そして、次のようHにキューブ状態への移動を実行しますG

m.rW}Hdd@...xZHG
m              G   map each piece d in G to:
 .rW   d              perform a rotated translation to d, but only if:
    }Hd                  H appears in d (d is currently on the face H)
            xZH           get the index of H in Z
        @...              and choose the code in the list of 6 (see above)

繰り返しの数を数える:

残りは非常に簡単です。以前に訪れた位置に到達するまで、解決されたキューブへの入力スクランブルを何度も繰り返します。

l.uu<apply move H to G><parsed scramble>N<solved state>
u...N   performs all moves of the scramble to the state N
.u...   do this until cycle detected, this returns all intermediate states
l       print the length

13

GAP、792 783 782 749 650バイト

これは機能しているようです。それが何かを台無しにしたら私に知らせてください。

原始的な動きのいくつかを分解することを提案してくれた@Lynnに感謝します。

代わりにInverse(X)を使用することを提案してくれた@Neilに感謝しますX^3

使用例: f("R");

R:=(3,39,21,48)(6,42,24,51)(9,45,27,54)(10,12,18,16)(13,11,15,17);L:=(1,46,19,37)(4,49,22,40)(7,52,25,43)(30,36,34,28)(29,33,35,31);U:=(1,10,27,28)(2,11,26,29)(3,12,25,30)(37,43,45,39)(40,44,42,38);A:=R*L^3*F*F*B*B*R*L^3;D:=A*U*A;;F:=(1,3,9,7)(2,6,8,4)(10,48,36,43)(13,47,33,44)(16,46,30,45);B:=(27,25,19,21)(26,22,20,24)(39,28,52,18)(38,31,53,15)(37,34,54,12);d:=NewDictionary((),true);AddDictionary(d,'R',R);AddDictionary(d,'L',L);AddDictionary(d,'U',U);AddDictionary(d,'D',D);AddDictionary(d,'F',F);AddDictionary(d,'B',B);f:=function(s) local i,p,b,t;p:=();
for c in s do if c='\'' then t:=t^2;else t:=LookupDictionary(d,c);fi;p:=p*t;od;return Order(p);end;

ここに、説明されていないコードなしのコードがあります

  # Here we define the primitive moves
R:=(3,39,21,48)(6,42,24,51)(9,45,27,54)(10,12,18,16)(13,11,15,17);
L:=(1,46,19,37)(4,49,22,40)(7,52,25,43)(30,36,34,28)(29,33,35,31);
U:=(1,10,27,28)(2,11,26,29)(3,12,25,30)(37,43,45,39)(40,44,42,38);
#D:=(7,34,21,16)(8,35,20,17)(9,36,19,18)(48,46,52,54)(47,49,53,51);
F:=(1,3,9,7)(2,6,8,4)(10,48,36,43)(13,47,33,44)(16,46,30,45);
B:=(27,25,19,21)(26,22,20,24)(39,28,52,18)(38,31,53,15)(37,34,54,12);

# Here we define D in terms of other primitive moves, saving on bytes
# Thanks @Lynn
# This is actually doable with a maximum of 3 of the primitive moves
# if a short enough sequence can be found.
D:=U^(R*L^3*F*F*B*B*R*L^3);

# create dictionary and add moves to it with appropriate char labels
d:=NewDictionary((),true);
AddDictionary(d,'R',R);
AddDictionary(d,'L',L);
AddDictionary(d,'U',U);
AddDictionary(d,'D',D);
AddDictionary(d,'F',F);
AddDictionary(d,'B',B);

f:=function(s)
    local c,p,t;

    # p will become the actual permutation passed to the function
    p:=();

    for c in s do
        if c='\'' then
            # The last generator we mutiplied (that we still have in t)
            # should have been its inverse. Compensate by preparing to
            # multiply it two more times to get t^3=t^-1. Thanks @Neil.
            t:=t^2;
        else
            t:=LookupDictionary(d,c);
        fi;
        p:=p*t;
    od;

    return Order(p);

end;

すべての動きはアイデンティティの4番目のルートであるため、インバースは不要です。
ニール

あなたはおそらくあなたの順列で置き換え455、3バイトを節約することができます。
リン

ベンソンIによって結果がSingmasterで見つかった、1981年は言う:「レッツA =RL⁻¹F²B²RL⁻¹、その後、AUA = D.」確かに、A:=R*L*L*L*F*F*B*B*R*L*L*L;D:=A*U*A;のためのあなたの定義よりも短くなっているD(しかし、私は...それをテストすることはできません)
リン

GAP ^-1では、逆関数の記述を本当に許可していませんか?
リン

うん、^-1を使用して完全に間隔を空けました。これは、@ Neilが言ったこととほとんど同じであると思いますが、^ 3(実際には最短)を使用している点が異なります。また、そうです、私は動きを他の動きに分解することができます、そして、そうすることで数バイトを節約できるはずです、それはただ最も短い分解を見つけることの問題でしょう。
リアム

10

Mathematica、413 401バイト

Evaluate[f/@Characters@"RFLBUD"]=LetterNumber@"ABFEJNRMDAEHIMQPCDHGLPTOBCGFKOSNADCBILKJEFGHQRST"~ArrayReshape~{6,2,4};
r[c_,l_]:=(b=Permute[c,Cycles@f@l];MapThread[(b[[#,2]]=Mod[b[[#,2]]+{"F","B","L","R"}~Count~l{-1,1,-1,1},#2])&,{f@l,{3,2}}];b);
p@s_:=Length[c={#,0}&~Array~20;NestWhileList[Fold[r,#,Join@@StringCases[s,x_~~t:""|"'":>Table[x,3-2Boole[t==""]]]]&,c,(Length@{##}<2||c!=Last@{##})&,All]]-1

説明

ルービックキューブは、20個の可動キュービ(8つのコーナー、12のエッジ)で構成されています。各キュービには番号を付けることができます:

コーナー

N   starting position
1     UFR
2     UBR
3     UBL
4     UFL
5     DFR
6     DBR
7     DBL
8     DFL

エッジ

N   starting position
9     UF
10    UR
11    UB
12    UL
13    FR
14    BR
15    BL
16    FL
17    DF
18    DR
19    DB
20    DL

立方体がねじれている場合、キュービは通常、開始位置にないことに注意してください。たとえば、終了するRと、キュービ1UFR新しい位置に移動しUBRます。

このような表記法では、90度の回転は、キュービィの8つの動きで表現できます。例えば、Rにより記載されています

from  to
UFR   UBR
UBR   DBR
DBR   DFR
DFR   UFR
UR    BR
BR    DR
DR    FR
FR    UR

各キュービには一意の開始位置があるため、各位置には一意の開始キュービがあります。つまり、ルールUFR->UBRはただです1->2Rキュービの開始位置にあるキュービ1をキュービの開始位置に移動することを意味します2)。したがって、Rサイクルをさらに簡素化できます

Cycles[{{1,2,6,5}, {10,14,18,13}}]

ルービックキューブを完全に解決するには、キュービを対応する開始方向に揃える必要もあります。立方体の面はさまざまな色で描かれています。立方体を解くときによく使うスキームは

face color
U    yellow
D    white
F    red
B    orange
R    green
L    blue

角の向きを分析するとき、黄色または白以外の色は無視され、黄色と白は同じ色と見なされます。

cubie 1が開始位置UFRにあり、黄色のファセットが3つの異なる面に位置合わせされているとします。これらのケースを表すために整数を使用しますが、

0  yellow on U  (correct)
1  yellow on R  (120 degree clockwise)
2  yellow on F  (120 degree counterclockwise)

cubie 1がオンのDFL場合、その3つの可能な向きは

0  yellow on D  (correct)
1  yellow on L  (120 degree clockwise)
2  yellow on F  (120 degree counterclockwise)

エッジの方向を分析するとき、赤とオレンジは無視され、黄色と白はエッジに緑または青のファセットがある場合にのみ無視されます。

cubie 10が開始位置URにあり、緑のファセットが2つの異なる面に位置合わせされているとします。その2つの可能な方向は

0  green on R  (correct)
1  green on U  (180 degree)

cubie 10がオンでDF、その2つの可能な向きが

0  green on D  (correct)
1  green on F  (180 degree)

配列は、キューブの状態を格納するために使用されます。キューブの開始状態は

{{1,0},{2,0},{3,0},{4,0},{5,0},{6,0},{7,0},{8,0},{9,0},{10,0},{11,0},{12,0},{13,0},{14,0},{15,0},{16,0},{17,0},{18,0},{19,0},{20,0}}

つまり、すべてのキュービィは正しい向きで開始位置にあります。

の後R、キューブの状態は

{{5,2},{1,1},{3,0},{4,0},{6,1},{2,2},{7,0},{8,0},{9,0},{13,1},{11,0},{12,0},{18,1},{10,1},{15,0},{16,0},{17,0},{14,1},{19,0},{20,0}}

これキュービーがあることを意味5位置になりました1UFR配向した)2、キュービーの1位置になりました2UBR配向した)1、キュービーの3位置に今もある3UBL向きに)0など。


テストケース

p["FF'"]            (* 1   *)
p["R"]              (* 4   *)
p["RUR'U'"]         (* 6   *)
p["LLUUFFUURRUU"]   (* 12  *)
p["LUFFRDRBF"]      (* 56  *)
p["LF"]             (* 105 *)
p["UFFR'DBBRL'"]    (* 120 *)
p["FRBL"]           (* 315 *)

7

Haskell、252バイト

r=[-2..2]
s=mapM id[r,r,r]
t m p@[x,y,z]=case m of"R"|x>0->[x,z,-y];"L"|x<0->[x,-z,y];"U"|y>0->[-z,y,x];"D"|y<0->[z,y,-x];"F"|z>0->[y,-x,z];"B"|z<0->[-y,x,z];c:"'"->t[c]$t[c]$t[c]p;_->p
f m=length$s:fst(span(/=s)$tail$iterate(flip(foldl$flip$map.t)m)s)

サンプルの実行:

*Main> f ["F","F'"]
1
*Main> f ["R"]
4
*Main> f ["R","U","R'","U'"]
6
*Main> f ["L","L","U","U","F","F","U","U","R","R","U","U"]
12
*Main> f ["L","U","F","F","R","D","R","B","F"]
56
*Main> f ["L","F"]
105
*Main> f ["U","F","F","R'","D","B","B","R","L'"]
120
*Main> f ["F","R","B","L"]
315
*Main> f ["R","U","U","D'","B","D'"]  -- maximum possible order
1260

ここで重要なのは、ルービックキューブを3×3×3の立方体のグリッドではなく、5×5×5の点のグリッドとしてモデル化する方が簡単だということです。コーナーキューブは2×2×2ポイントの立方体になり、エッジキューブは2×2×1ポイントの正方形になり、5×5×2ポイントのスライスを回転させます。


これは本当に賢いです!で置き換えるc:"'"c:_2バイト節約できると思います。
リン

ありがとう!私はテストケース用に1260シーケンスを探していましたが、それを調べるのは面倒でした:)
Geobits

@Lynn、_空のリストにも一致するため機能しません。
アンデルスカセオルグ16

これは素晴らしいことですが、別の質問codegolf.stackexchange.com/a/44775/15599に対するこの回答と非常によく似ています。それに触発されたなら、それを認めるべきです。
レベルリバーセント

@steveverrill、すごい、それは印象的に似ていますが、いや、私はそれを見ていませんでした。私の答えは私自身の独立した仕事です。(もちろん、ヤン・ドヴォルザークは私がやる前にほとんど同じアイデアを思いついたと認めています。)
Anders Kaseorg

7

ルビー、225バイト

->s{n=0
a=[]
b=[]
64.times{|i|a<<j=[(i&48)-16,(i&12)-4,i%4-1];b<<j*1}
d=1
(n+=1
s.reverse.chars{|c|m="UFRDBL".index(c)
m ?(e=m/3*2-1
b.each{|j|j[m%=3]*e>0&&(j[m-2],j[m-1]=j[m-1]*e*d,-j[m-2]*e*d)}
d=1):d=-1})until n>0&&a==b
n}

Anders Kaseorgの回答と同様で、前の質問に対する Jan Dvorakの回答に触発されました。

ただし、これらの回答とは異なり、125個のキュービックは必要ありません。私は27立方体のルビックキューブを使用していますが、寸法は長方形です。解決された状態では、角はにあり+/-1,+/-4,+/-16ます。

64個の立方体の配列を生成しx=[-1,0,1,2], y=[-4,0,4,8], z=[-16-0,16,32]ます。各立方体はから選択されます。座標が2、8、32のキュービは不要ですが、害はないため、ゴルフの理由で残されています。立方体の長さ、幅、深さが異なるという事実:(1,4,16)は、それらが正しい場所にあるが向きが間違っているかどうかを簡単に検出できることを意味します。

各キュービは、フェイスターンによって動かされるときに追跡されます。(e=-1U、F、Rまたはe=1D、B、L に対して乗算される)面に対応する軸のキュービィの座標が正の場合、他の2軸の座標を交換して適用することにより回転します適切な符号が座標の1つに変わります。これはを掛けることで制御されe*dます。

入力シーケンスは逆の順序でスキャンされます。「通常の」回転が時計回りではなく反時計回りに実行される限り、これは違いを生じません。これは、'シンボルが見つかった場合d、次の面を反対方向に回転させるために、値を1から-1に変更できるようにするためです。

テストプログラムでゴルフをしていません

f=->s{n=0                                      #number of repeats=0
  a=[]                                         #empty array for solved position
  b=[]                                         #empty array for current position
  64.times{|i|
    a<<j=[(i&48)-16,(i&12)-4,i%4-1]            #generate 64 cubies and append them to the solved array
    b<<j*1                                     #duplicate them and append to active array
  }
  d=1                                          #default rotation direction anticlockwise (we scan the moves in reverse)                              
  (                                            #start of UNTIL loop
    n+=1                                       #increment repeat counter
    s.reverse.chars{|c|                        #reverse list of moves and iterate through it
      m="UFRDBL".index(c)                      #assign move letter to m (for ' or any other symbol m is false)
      m ?                                      #if a letter
        (e=m/3*2-1                             #e=-1 for UFR, 1 for DBL
        b.each{|j|                             #for each cubie 
          j[m%=3]*e>0&&                        #m%=3 picks an axis. If the cubie is on the moving face of the cube
         (j[m-2],j[m-1]=j[m-1]*e*d,-j[m-2]*e*d)#rotate it: exchange the coordinates in the other 2 axes and invert the sign of one of them according to direction
        }                                      #as per the values of e and d. 
        d=1                                    #set d=1 (in case it was -1 at the start of the b.each loop)
      ):
      d=-1                                     #ELSE the input must be a ', so set d=-1 to reverse rotation of next letter
    }
   )until n>0&&a==b                            #end of UNTIL loop. continue until back at start position a==b
n}                                             #return n

p f["FF'"]               #      1
p f["R"]                 #      4
p f["RUR'U'"]            #      6
p f["LLUUFFUURRUU"]      #     12
p f["LUFFRDRBF"]         #     56
p f["LF"]                #    105
p f["UFFR'DBBRL'"]       #    120
p f["FRBL"]              #    315

7

Python 2、343バイト

def M(o,v,e):
 k=1
 for m in e:
  for c in'ouf|/[bPcU`Dkqbx-Y:(+=P4cyrh=I;-(:R6'[m::6]:i=~ord(c)%8*k;j=(ord(c)/8-4)*k;o[i],o[j]=o[j]-m/2,o[i]+m/2;v[i],v[j]=v[j],v[i];k=-k
V=range(20)
o,v,e=[0]*20,V[:],[]
for c in raw_input():i='FBRLUD'.find(c);e+=i<0and e[-1:]*2or[i]
M(o,v,e);n=1
while any(o[i]%(2+i/12)for i in V)or v>V:M(o,v,e);n+=1
print n

入力は標準入力から取得されます。

与えられたねじれのシーケンスは、解決された状態に戻るまで、仮想キューブで繰り返し実行されます。立方体の状態は、長さ20の方向ベクトルと順列ベクトルとして保存されます。

方向はいくぶんarbitrarily意的に定義されます。RまたはLの4分の1ターンを呼び出さずに所定の位置に移動できる場合、エッジキューブは正しい方向に向けられます。コーナーキューブの方向は、F面とB面を基準にして考慮されます。


サンプルの使用法

$ echo FRBL|python rubiks-cycle.py
315

$ echo RULURFLF|python rubiks-cycle.py
1260

オンラインデモンストレーションおよびテストスイート


3
関数名と引数の素晴らしい選択!
ニール

3

Clojure、359バイト

これは私の2番目に長いcodegolfかもしれません。私はベクトルAから末尾のゼロをドロップしFて私を非常に幸せにすることができることに気づいた:D

#(let[I(clojure.string/replace % #"(.)'""$1$1$1")D(range -2 3)S(for[x D y D z D][x y z])A[0 1]B[0 0 1]C[1]D[-1]E[0 -1]F[0 0 -1]](loop[P S[[n R]& Q](cycle(map{\F[A[B A D]]\B[E[F A C]]\L[D[C B E]]\R[C[C F A]]\U[B[E C B]]\D[F[A D B]]}I))c 0](if(=(> c 0)(= P S))(/ c(count I))(recur(for[p P](if(>(apply +(map * n p))0)(for[r R](apply +(map * r p)))p))Q(inc c)))))

少ないゴルフ:

(def f #(let [I (clojure.string/replace % #"(.)'""$1$1$1")
              D [-2 -1 0 1 2]
              S (for[x D y D z D][x y z])
              L   {\F [[ 0  1  0][[0  0  1][ 0 1  0][-1  0 0]]]
                   \B [[ 0 -1  0][[0  0 -1][ 0 1  0][ 1  0 0]]]
                   \L [[-1  0  0][[1  0  0][ 0 0  1][ 0 -1 0]]]
                   \R [[ 1  0  0][[1  0  0][ 0 0 -1][ 0  1 0]]]
                   \U [[ 0  0  1][[0 -1  0][ 1 0  0][ 0  0 1]]]
                   \D [[ 0  0 -1][[0  1  0][-1 0  0][ 0  0 1]]]}]
          (loop [P S c 0 [[n R] & Q] (cycle(map L I))]
            (if (and (> c 0) (= P S))
              (/ c (count I))
              (recur (for[p P](if(pos?(apply +(map * n p)))
                                (for[r R](apply +(map * r p)))
                                p))
                     (inc c)
                     Q)))))

これは、選択した5 x 5 x 5キューブのサブセットの3D回転を実装するだけです。もともと私は使用するつもりでしたが3 x 3 x 3、なぜ正しい結果が得られなかったのかを理解するのに時間がかかりました。良いテストケース!"RUR'U'"としてエンコードするためのいくつかの余分なバイト"RURRRUUU"


3

通常9 6バイト

¶-7)8%

オンラインでお試しください!(デニスがTIO Cubicallyインタープリターを更新するまで非作業)

説明:

¶-7)8%
¶       read a string, insert into code
 -7     add 1 to notepad (subtracts the 7th face "sum" from notepad, defaulted to -1)
   )8   jump back to start of code if cube unsolved
     %  print notepad

この言語は、すべての課題を支配します>:D


3
これらすべての新しい絡み合ったエソラン。戻る私の一日で、-7意味減算7は、1を追加しないで怒っウォーカーを振る
caird coinheringaahing

@cairdcoinheringaahing確かに。:Pそれに関する説明を追加しました。
MD XF

1

クリーン、255バイト

この質問に対する回答として、ほぼ同一のHaskellの回答とは別に導き出されました。この質問は、ほぼ終了時に複製として閉じられたため、ここに回答を投稿しました。

import StdEnv,StdLib
a=[-2..2];b=diag3 a a a
?m=iter(size m*2-1)\p=:(x,y,z)=case m.[0]of'F'|z>0=(y,~x,z);'U'|y>0=(~z,y,x);'R'|x>0=(x,z,~y);'B'|z<0=(~y,x,z);'D'|y<0=(z,y,~x);'L'|x<0=(x,~z,y);_=p
$l=length(takeWhile((<>)b)(tl(iterate(map(sseq(map?l)))b)))+1

オンラインでお試しください!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.