Rubik ile Bisiklete binme


43

Boşta Rubik küpümü etrafında döndürürken, oğlum çözüldü durumuna geri döndüğünü fark etti. İlk başta bunun bir çeşit vudu büyüsü olduğunu düşündüğünden eminim ama aynı hamle sırasını tekrarlamaya devam edersen her zaman orijinal durumuna geri döneceğini açıkladım. Sonuçta.

Elbette, çocukken, kendisi için denemek zorunda kaldı ve aldatıcı olacağını düşündüğü "rastgele" bir diziyi seçti. On defa tekrarladıktan sonra izini kaybetti ve kaç kez tekrar etmesi gerektiğini sordu. Kullandığı sırayı bilmeden ona bilmediğimi söyledim, ancak bunu bulmak için bir program yazabileceğimizi söyledim.

Sen devreye giriyorsun Bu benim, tabii ki. Olduğu could sadece kırbaç birşeyler ama kendi başına bunu yazın istiyorum. Yine de çok hızlı bir daktilo değildir, bu yüzden mümkün olan en kısa programa ihtiyacım var .

Amaç

Bir sıra sırası göz önüne alındığında, küpü orijinal durumuna döndürmek için yapılması gereken en az sayıda çıktı alın. Bu kod golf, yani en az bayt kazanıyor. Bir program veya işlev yazabilirsiniz ve diğer tüm varsayılan ayarlar uygulanır.

Giriş

Giriş, dize, liste veya dilinize uygun başka bir biçim olarak alınan bir hareketler dizisidir. Dize biçimindeyse, hareketler arasında bir ayırıcı (veya kullanmamak) kullanmaktan çekinmeyin.

Dikkatleri ile birlikte dikkate alınması gereken altı "temel" hareket vardır:

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

Ters çevrmeler ', harften sonra bir ana işaret eklenerek gösterilir . Bu, o yüzü saatin tersi yönünde çevirdiğinizi, bu nedenle F'ön yüzü saatin tersi yönünde çevirdiğinizi ve F F'hemen orijinal durumuna döndüreceğinizi gösterir.

İlgilenenler için bu zorluk sınırlı sayıda Singmaster Notation kullanıyor . Ruwix'in güzel animasyonları var, eğer görmek istiyorsan.

Çıktı

Çıkış, giriş sırasının gerçekleştirilmesi gereken minimum sayıdır.

Örnekler

Input                Output

FF'               ->      1
R                 ->      4
RUR'U'            ->      6
LLUUFFUURRUU      ->     12
LUFFRDRBF         ->     56
LF                ->    105
UFFR'DBBRL'       ->    120
FRBL              ->    315

İşte Java ile yazılmış cevaplarınızı karşılaştırmak için (saf) bir çözücü. Aynı zamanda 2çift ​​hamle kabul eder (bu yüzden dördüncü durum eşittir 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;
        }
    }
}

"saat yönünde", "yüze dönükken saat yönünde" anlamına gelir.
msh210

@ msh210 Doğru.
Geobits

7
Soyulma noktasında, yeterli olan en küçük sayıyı istediğinizi açıkça belirtmeniz gerektiğini düşünüyorum . Aksi halde grubun büyüklüğünü çıkartabilir ve Lagrange teoreminden alıntı yapabilirdim ...
Peter Taylor

2
@PeterTaylor Pedantry kabul edildi.
Geobits

4
Ben olabilir Shuffle bir çözüm için 500 nokta ödül sunuyoruz. Henüz emin değilim.
lirtosiast

Yanıtlar:


16

Pyth, 66 63 bayt

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

Çevrimiçi deneyin: Gösteri veya Test Paketi . Programın biraz yavaş olduğuna ve çevrimiçi derleyicinin yanıtını hesaplayamadığına dikkat edin RU2D'BD'. Ancak, dizüstü bilgisayarımda yaklaşık 12 saniye içinde hesaplayabileceğinden emin olabilirsiniz.

Program (yanlışlıkla) aynı zamanda 2çift ​​hamle için kabul eder.

Tam açıklama:

Ayrıştırma kapış:

İlk önce 'girdi dizgilerindeki asal işaretlerle ilgileneceğim . Bunları basitçe değiştiririm 3ve bu dizgede kod uzunluğu çözülür. Pyth'in kod çözme formatı, karakterin önündeki sayıyı gerektirdiğinden, dizgeyi önceden tersine çeviririm. _r_Xz\'\39. Böylece daha sonra geri çeviriyorum.

Çözülen küp durumunu tanımlayın:

=Z"UDLRFBTüm 6 hamle ile dize atar Z.

Her küp parçasının yerini tanımlayarak bir küp durumunu tanımlayabiliriz. Örneğin, UL (Yukarı-Sol) konumunda olması gereken kenarın şu anda FR'de (Ön-Sağ) olduğunu söyleyebiliriz. Bunun için ben çözüldü küpün tüm parçaları üretmek gerekir: f!s}RTcZ2yZ. yZtüm olası altkümelerini oluşturur "UDLRFB". Bu açıkça alt kümeyi "UDLRFB"ve alt kümeyi de oluşturur "UD". İlki hiçbir anlam ifade etmiyor, çünkü 6 taraftan görülebilen bir parça yok ve ikincisi de hiçbir anlam ifade etmiyor, çünkü kenardan bir parça yok, üstten ve alttan görülebilen bir parça var. . Bu yüzden altdizisi içeren tüm alt kümelerini kaldırmak "UD", "LR"ya da "FB". Bu bana aşağıdaki 27 adet verir:

'', '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'

Bu, boş dizgiyi ve altı adet 1 harfli dizgiyi de içerir. Onları küpün ortasındaki parça ve 6 orta parça olarak yorumlayabiliriz. Açıkçası onlar gerekli değildir (hareket etmediklerinden beri), ama ben onları tutacağım.

Bazı hamle yapmak:

Bir hamle yapmak için bazı dize çevirileri yapacağım. Bu fikri görselleştirmek için içerideki köşe kısmına bakın URF. Bir Rhamle yaptığımda ona ne olacak ? Çıkartmadadır Uyüze hamle Byüz, sticker Fgeçer Uyüz ve etikete Rde yüz kalır Ryüzü. Söyleyebileceğimiz, parçanın URFpozisyonuna geçtiğini söyleyebiliriz BRU. Bu desen sağ taraftaki tüm parçalar için geçerlidir. Üzerinde her etiket Fiçin yüz hamle Ubir zaman yüzünde Rhareket yapılır, üzerinde her etiket Uiçin yüz hamle Byüzünde, her etiket Biçin hamle Düzerine ve her etiket Diçin hamleF. Bir Rhamlenin değişimlerini olduğu gibi çözebiliriz FUBD.

Aşağıdaki kod gerekli tüm 6 kodu oluşturur:

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

Ve Haşağıdaki gibi küp durumuna Ggeçiyoruz:

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)

Tekrar sayısını sayın:

Gerisi çok önemsiz. Daha önce ziyaret ettiğim bir konuma gelinceye kadar çözülen küpün girişini karıştırıp tekrar tekrar yapıyorum.

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 Bayt

Bu çalışıyor gibi görünüyor. Bir şeye karışırsa bana haber ver.

İlkel hamlelerin bazılarını parçaladığımı önerdiği için @ Lynn'e teşekkür ederim.

Yerine düşündürmektedir için @Neil sayesinde Inverse(X)kullandığım X^3.

Kullanım örneği: 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;

İşte biraz açıklama ile ungolfed kodu

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

Her hareket, kimliğin dördüncü bir köküdür, bu yüzden Tersiniz gereksizdir.
Neil

Muhtemelen yerini alabilir 45ile 5sizin permütasyonlarda ve üç bayt kaydedin.
Lynn,

Benson I tarafından bir sonuç Singmaster bulunan 1981 diyor ki: “Let A = RL⁻¹F²B²RL⁻¹ ardından AUA = D” Gerçekten de, A:=R*L*L*L*F*F*B*B*R*L*L*L;D:=A*U*A;için tanım daha kısadır D(ama ... bunu test edemez)
Lynn

GAP gerçekten sizin için yazmanıza izin vermiyor mu ^-1, BTW?
Lynn,

Evet ^ -1 kullanarak tamamen boşluk bıraktım. Sanırım @Neil'in söylediği şey neredeyse aynı, bunun yerine ^ 3 dışında (ki en kısa olanı). Ayrıca, evet, hamleleri diğer hamlelere ayırabilirim ve bunu yaparak birkaç byte tasarruf edebilmeliydim, bu sadece en kısa bozunmayı bulma meselesi olacaktı.
Liam,

10

Mathematica, 413 401 bayt

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

açıklamalar

Bir Rubik Küpü 20 hareketli küpten (8 köşe, 12 kenar) oluşur. Her küpeye bir numara verilebilir:

köşeler :

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

kenarlar :

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

Küp büküldüğünde, küplerin genellikle başlangıç ​​pozisyonlarında olmadıklarına dikkat edin. Örneğin R, yapıldığında, küp yeni bir pozisyona 1hareket eder .UFRUBR

Böyle bir gösterimde, 90 derece dönüş, 8 küp hareketle tanımlanabilir. Örneğin, Rtarif edilmektedir

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

Her bir küpün kendine özgü bir başlangıç ​​konumu olduğundan, her bir konum için benzersiz bir başlangıç ​​küpü vardır. Bu kural, demek ki UFR->UBRadildir 1->2(vasıta Rcubie başlangıç pozisyonuna cubie alır 1cubie başlangıç pozisyonuna 2). Böylece Rbir çevrime ilerletilebilir

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

Bir Rubik Küpünü tamamen çözmek için, küpleri karşılık gelen başlangıç ​​yönleriyle aynı hizaya getirmemiz gerekir. Bir küpün yüzleri farklı renklerle boyanmış, küpleri çözerken sıklıkla kullandığım şema

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

Köşelerin yönlerini analiz ederken, sarı veya beyaz dışındaki renkler göz ardı edilir ve sarı ve beyaz aynı renk olarak kabul edilir.

Cubie'nin 1başlangıç ​​konumunda olduğunu varsayalım UFR, sarı faset üç farklı yüze hizalanabilir. Bu davaları temsil etmek için bir tamsayı kullanıyoruz.

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

Diyelim ki cubie 1açık DFL, üç olası yönü

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

Kenarların yönelimlerini incelerken, kırmızı ve turuncu göz ardı edilir ve sarı ve beyaz, yalnızca kenarı yeşil veya mavi bir yüzü varsa göz ardı edilir.

Küpün 10başlangıç ​​konumunda olduğunu varsayalım UR, yeşil yüz iki farklı yüze hizalanır. İki olası yönelimi

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

Diyelim ki cubie 10açık DF, iki olası yönü

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

Bir küpün durumunu depolamak için bir dizi kullanılır. Bir küpün başlangıç ​​durumu

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

bu, her bir kübün doğru pozisyonda başlangıç ​​pozisyonunda olduğu anlamına gelir.

Sonra Rküpün durumu

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

yani, küp 5şu anda 1( UFR) oryantasyonda 2, küp 1şu anda 2( UBR) oryantasyonda 1, küp 3şu an 3( UBL) oryantasyonda 0ve (vb.) konumunda.


Test durumları

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 bayt

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)

Örnek çalışır:

*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

Buradaki en önemli gözlem Rubik küpünün 3 x 3 x 3 odaklı bir kübik ızgara yerine 5 x 5 x 5 nokta ızgarası olarak modellenmesinin daha kolay olduğudur. Köşe küpleri 2 × 2 × 2 puan küp, kenar küpleri 2 × 2 × 1 puan kareler haline gelir ve hamle 5 × 5 × 2 puan dilimleri döndürür.


Bu gerçekten zekice! İki bayt c:"'"ile değiştirmeyi düşünüyorum c:_.
Lynn,

Teşekkürler! Test vakaları için bir 1260 sekansı arıyordum, fakat onu ararken rahatsız olamazdı :)
Geobits

@ Lynn, bu _boş liste ile de eşleştiği için çalışmıyor .
Anders Kaseorg

Bu harika, ancak bu cevaba çok benzer görünüyor, codegolf.stackexchange.com/a/44775/15599 . Bundan ilham aldıysanız, onaylamanız gerekir.
Seviye Nehri St

@ steveverrill, vay, bu etkileyici bir şekilde benzer görünüyor, ama hayır, onu görmedim. Cevabım kendi bağımsız çalışmalarım. (Tabii ki, Jan Dvorak'ın benden önce aynı fikirlerin çoğuyla geldiğini kabul ediyorum.)
Anders Kaseorg

7

Ruby, 225 bayt

->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'un cevabına benzer şekilde ve Jan Dvorak'ın önceki bir soruya verdiği yanıttan ilham aldı .

Ancak bu cevapların aksine, 125 küvete ihtiyacım yok. Bir rubik küpünü 27 küp ama dikdörtgen boyutta kullanıyorum. Çözülmüş halde, köşeler vardır +/-1,+/-4,+/-16.

Her biri merkezden seçilen 64 bir dizi küp üretiyorum x=[-1,0,1,2], y=[-4,0,4,8], z=[-16-0,16,32]. 2, 8 ve 32 koordinatlarına sahip yavrular gereksizdir, ancak zarar vermezler, bu yüzden golf oynamak için kalırlar. Küplerin uzunluğunun, genişliğinin ve derinliğinin farklı olması: (1,4,16) doğru yerde olup olmadıklarının yanlış oryantasyon ile tespit edilmesinin kolay olduğu anlamına gelir.

Her bir küp faset tarafından hareket ettirilirken izlenir. Yüze karşılık gelen eksende bir küpün koordinatı ( e=-1U, F, R veya e=1D, B, L için çarpılır ) pozitifse, o zaman koordinatları diğer 2 ekseninde değiştirip döndürerek döndürülür. Koordinatlardan birine uygun işaret değişikliği. Bu çarpılarak kontrol edilir e*d.

Giriş sırası ters sırada taranır. Bu, "normal" döndürmeler saat yönünde değil saat yönünün tersine gerçekleştirildiği sürece fark yaratmaz. Bunun nedeni, eğer bir 'sembol bulunursa, dtakip eden yüzün zıt yönde dönmesini sağlamak için değeri 1'den -1'e değiştirilebilir.

Test programında Ungolfed

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 bayt

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

Girdi stdin'den alınmıştır.

Verilen bükülme dizisi sanal bir küp üzerinde çözülen duruma dönene kadar tekrar tekrar gerçekleştirilir. Küp durumu, her ikisi de 20 uzunluğunda bir oryantasyon vektörü ve permütasyon vektörü olarak depolanır.

Oryantasyonlar bir şekilde keyfi olarak tanımlanır: bir R veya L çeyrek dönüşü çağırmaksızın yerine getirilebiliyorsa, kenar küberi doğru yönlendirilir. Köşe küplerinin yönü, F ve B yüzlerine göre kabul edilir.


Örnek Kullanım

$ echo FRBL|python rubiks-cycle.py
315

$ echo RULURFLF|python rubiks-cycle.py
1260

Çevrimiçi Gösteri ve Test Paketi .


3
Fonksiyon adı ve argümanların güzel bir seçim!
Neil

3

Clojure, 359 bayt

Bu benim en uzun 2. kodgolf olabilir. Ben vektörler gelen ardarda sıfırları düşebilir fark Aetmek Fbeni çok mutlu etti: 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)))))

Daha az golf oynadı:

(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)))))

Bu sadece seçilen 5 x 5 x 5küp alt kümelerinin 3B dönüşlerini uygular . İlk başta kullanacaktım 3 x 3 x 3ve neden doğru sonuçlar alamadığımı anlamam biraz zaman aldı. İyi test vakaları! Bazı ekstra yumruk kodlama için bayt "RUR'U'"olarak "RURRRUUU".


3

Kübik olarak , 9 6 bayt

¶-7)8%

Çevrimiçi deneyin! (Dennis TIO’nun Kübik tercümanını güncelleyene kadar çalışmaz)

Açıklama:

¶-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

Bu dil tüm zorluklarına >: D


3
Tüm bu yeni fangled esolangs. Benim zamanımda, içinde -7bir tane eklemek değil yedi çıkarma anlamına öfkeyle yürüteç sallar
coinheringaahing Caird

@cairdcoinheringaahing Indeed. : P Bununla ilgili bazı açıklamalar eklendi.
MD XF

1

255 bayt temiz

Neredeyse aynı olan Haskell cevabından ayrı olarak türetilmiş bu sorunun cevabı , neredeyse bittiğinde kopya olarak kapatılan bu sorunun cevabı olarak ortaya çıktı, ben de cevabı buraya yazdım.

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

Çevrimiçi deneyin!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.