Perebutan Kubus Rubik

21

Tugas Anda adalah membuat urutan gerakan secara acak, yang dapat digunakan untuk mengacak Rubik's Cube. Perebutan seperti itu terdiri dari 25 gerakan. Setiap gerakan terdiri dari huruf-huruf yang UDRLFBsecara opsional diikuti oleh salah satu sufiks '2.

Notasi ini disebut notasi Singmaster. UDRLFBmewakili salah satu dari 6 wajah dan akhiran opsional '2mewakili sudut belok. Informasi ini sama sekali tidak diperlukan untuk menyelesaikan tugas.

Untuk memastikan, bahwa perebutan adalah 'berkualitas baik', dua aturan berikut harus diterapkan:

  • Dua gerakan berurutan tidak boleh memiliki huruf yang sama. Ini melarang bergerak berturut-turut UU, DD, RR, LL, FFdan BBdan semua kombinasi mereka menggunakan akhiran opsional seperti U2Uatau U'U'.

    Pasangan bergerak ini dilarang, karena mereka dapat dengan mudah dikurangi menjadi 1 atau 0 bergerak. U2Umemiliki efek yang sama dengan U', R'Refek yang sama dengan .

  • Tiga gerakan berurutan tidak boleh dari grup surat yang sama. Grup surat adalah UD, RLdan FB. Aturan ini juga melarang bergerak berturut-turut UDU, DUD, RLR, LRL, FBF, BFBdan semua kombinasi mereka menggunakan akhiran opsional seperti U2DU, RL'Ratau B2FB'.

    Kelompok-kelompok mengurutkan wajah berdasarkan sumbu gerak mereka. Udan Dberada dalam kelompok yang sama, karena keduanya berbalik pada poros yang sama. Karena itu sebuah Ugerakan tidak memengaruhi bagian-bagian Dwajah, dan sebuah Dgerakan tidak memengaruhi bagian-bagian Uwajah. Oleh karena itu kedua gerakan dapat dipertukarkan, UDUmemiliki efek yang sama dengan UUD, dan ini dapat dikurangi menjadi U2D.

Tantangan

Tulis skrip atau fungsi, yang menghasilkan satu perebutan acak. Tidak ada input. Script / fungsi harus mencetak 25 gerakan tanpa pemisahan atau dipisahkan oleh satu spasi atau mengembalikan string koresponden.

Program Anda harus dapat membuat setiap perebutan tunggal, yang memenuhi aturan di atas. Tentu saja dengan asumsi, bahwa generator angka acak adalah benar-benar acak, dan bukan pseudo acak.

Ini adalah kode-golf. Kode terpendek (dihitung dalam byte ) menang.

Contoh output:

Memanggil script / fungsi 3 kali harus mencetak / mengembalikan sesuatu seperti:

R'B2R2F2R2FB'R2DR2ULFB2RB'U2B'FL'BR'U'RB'
U'DBR'B2U'B'U'RUF'B'RDR2U'B'LR'B'F2D2UF2L'
BR2F'B'R'D'R'U2B'F2D2R'F2D'F'D2R2B'L2R'UB'R2L'D

Jika Anda memisahkan gerakan dengan spasi masing-masing:

R2 L' F2 U2 D' R2 L2 F L' D2 U R B D' U2 L B2 L U B2 D U2 R' D2 U'
B R D2 F U2 B' R2 F2 B' U' L' R2 B U2 R' D B' F' U2 R' B' L R D2 R2
B2 R2 U D' B R D' R L2 D2 L2 R B2 F U' F2 B2 U' F U' D F R2 U2 B'

Perhatikan, bahwa semua output ini terdiri dari 25 gerakan, tetapi memiliki panjang yang berbeda, karena sufiks opsional. Tidak diperbolehkan mencetak spasi, saat salah satu 2atau 'sedang digunakan sebagai sufiks. Anda harus mencetak L2UR2F'R'U2atau L2 U R2 F' R' U2. L2U R2F'R'U2tidak diizinkan.

Jakube
sumber
Apakah maksud Anda UR 2tidak diizinkan? U R2 harus diizinkan, saya pikir, karena ruang antar gerakan masuk akal.
mbomb007
@ mbomb007 Maksudku hal-hal seperti L2U R2F'R'U2. Utidak memiliki akhiran opsional dan karenanya tidak boleh memiliki spasi. Ruang tidak boleh menjadi pengganti untuk akhiran opsional.
Jakube
Bagaimana jika ada ruang di antara setiap gerakan? Bisakah kita menghasilkan U F2 L D2 R'..., misalnya? Dalam hal ini, tidak ada ruang ekstra , yang menurut saya harusnya oke menurut aturan Anda.
mbomb007
@ mbomb007 Ya, saya akan memasukkannya ke dalam deskripsi.
Jakube
Bukankah 2 sebelum surat itu? oO
Oliver Ni

Jawaban:

6

CJam, 47 45 byte

Solusi ini menggunakan pendekatan yang berbeda dari yang lainnya sejauh ini. Ini mengambil keuntungan dari operasi daftar singkat CJam untuk menghasilkan daftar langkah yang tersedia dan memilih satu secara acak setiap iteraton. Pengubah hanya dihasilkan secara independen.

Cobalah online.

{BA^2/6,_B-?A:B-mr0=:A"UDRLFB"=3mr[L2'']=}25*

Penjelasan

{               "Loop...";
  BA^2/           "If the two previous moves were not from the same group, ...";
  6,              "... then produce the available move list [0 1 2 3 4 5], ...";
  _B-             "... else produce the available move list [0 1 2 3 4 5] with
                   the second previous move removed";
  ?
  A:B             "Save the previous move as the second previous move";
  -               "Remove the previous move from the available move list";
  mr0=            "Randomly select an available move";
  :A              "Save this move as the previous move";
  "UDRLFB"=       "Map this move to its character (implicitly printed)";
  3mr[L2'']=      "Randomly select a modifier (implicitly printed)";
}25*            "... 25 times";
Runer112
sumber
9

C, 129

f(){int i,n,m,r,s,t;for(i=26;i--;i<25&&printf("%c%c","URFDLB"[s%6],"'2"[r%3])){for(n=m,t=1;t;t=m*n==9)m=(r=rand()%15)/3+1;s+=m;}}

Loop dalam menghasilkan nilai mdalam rentang 1..5yang ketika ditambahkan sdan diambil modulo 6, memastikan bahwa tidak ada dua gerakan berturut-turut berada di sisi yang sama dari kubus. Nilai lama mdisimpan dalam ndan tes m*n==9memastikan bahwa nilai m= 3 tidak pernah dihasilkan dua kali berturut-turut (sehingga wajah yang berlawanan tidak dapat diambil dua kali berturut-turut; perhatikan urutan wajah dalam string.)

Bagian paling tidak signifikan rdigunakan untuk memutuskan suffix ( ', 2atau null) mana yang akan digunakan, mengambil keuntungan dari karakter null di akhir "'2".

Loop luar berjalan 26 kali. Pertama kali, Utidak pernah bisa dipetik, sehingga printfditekan untuk iterasi pertama.

Kode yang tidak digabungkan dalam program pengujian

Kode ungolfed memberi jarak antara setiap gerakan untuk kejelasan (kode golf tidak, untuk menghemat satu byte.) Selain itu kode golf menyimpan titik koma dengan memindahkan bagian printfdalam forbraket.

f(){
  int i,n,m,r,s,t;
  for(i=26;i--;){
    for(n=m,t=1;t;t=m*n==9)m=(r=rand()%15)/3+1;
    s+=m;
    i<25&&printf("%c%c ","URFDLB"[s%6],"'2"[r%3]);
  }
}

main(){
  int j;
  srand(time(0));
  for(j=0;j<5;j++)f(), puts("");
}

Output khas

U' B D2 B' R' L F' D2 B D2 B2 R' B2 U D2 F' R U R' L B' L R2 B2 F'
U B U B F L2 D2 B' U' L B L R' D B U' D R D' B' F2 D' B D R
L D F2 B2 R' U F B' D2 L U R' L' U2 F' R F D U2 B L' B' U L2 F'
R2 B' F2 R2 L2 F' U2 L U' B' F R' D' F2 D F' L2 U2 R' D' B2 D F R2 L'
U2 F2 B2 D' F D F R L2 U' B D2 L' R D R F2 R' F2 U2 D R' D2 L F2
Level River St
sumber
124 byte
MD XF
118 byte
ceilingcat
4

Pyth, 65 66

Saya tidak pernah benar-benar bermain golf di Pyth, mungkin menulis satu atau dua program. Ini pada dasarnya adalah solusi @ steveverrill yang diterjemahkan ke Pyth. Saran perbaikan dipersilahkan.

Pembaruan: ditambahkan 1 byte untuk membuat perebutan juga dimulai dengan U. Mungkin solusi C mengandalkan perilaku yang tidak terdefinisi untuk membuatnya bekerja ...

=YO6V25JZK1WK=GO15=Z/+3G3=Kq9*ZJ)~YZpd+@"URFDLB"%Y6?@"'2"%G3>2%G3k

Saya percaya ini harus dilakukan dengan tugas yang lebih sedikit, tetapi itu akan mengharuskan saya untuk memodifikasi banyak algoritma. (Yah, mungkin mencoba.)

Berikut penjelasan berdasarkan kode C:

=YO6           s = random.choice(range(6))
V25            for i in range(25):
  JZ               n = m
  K1               t = 1
  WK               while t:
    =GO15              r = random.choice(range(15))
    =Z/+3G3            m = (r + 3) / 3
    =Kq9*ZJ            t = 9 == m * n
  )
  ~YZ              s += m
  pd               print(..., end = " ")
  +                ... + ...
  @"URFDLB"%Y6     "URFDLB"[s % 6]
  ?@"'2"%G3>2%G3k  "'2"[G % 3] if 2 > G % 3 else ""
PurkkaKoodari
sumber
Ganti variabel Ydan Z. Zdiinisialisasi dengan 0, sehingga Anda menyimpan 3 karakter pertama.
Jakube
@Jakube Tapi kemudian saya perlu mengatur n = m(baris penjelasan ke-3), yang harus berarti n = 0pertama kali, yang pada gilirannya akan perlu Ymenjadi 0.
PurkkaKoodari
Ydiinisialisasi dengan daftar kosong []. Dan saya tidak berpikir nilai dari nhal dalam iterasi pertama.
Jakube
Btw, kode Anda tidak menghasilkan pengacakan yang dimulai dengan U.
Jakube
@ Jakube terima kasih, sudah diperbaiki.
PurkkaKoodari
4

JavaScript (ES6) 175 178 204

Edit 3 byte lebih sedikit, 1 dengan mengubah kode dan 2 dengan mengubah cara byte dihitung (tidak termasuk F=)

Kode untuk menghindari repetitons diambil dari @stevemiller. Caranya mengelola grup surat bahkan lebih baik, tapi aku tidak akan mencurinya.

Bonus: Anda dapat menentukan jumlah gerakan secara opsional.

(n=25,R=n=>Math.random()*n|0)=>(r=>{for(N=_=>'UDRLFB'[(r-=~R(5))%6],b=N(a=N(s=''));n;~(a+b+c).search('^([UD]*|[RL]*|[FB]*)$')?0:s+=(--n,a=b,b=c)+["","'",2][R(3)])c=N()})(0)||s

Kurang golf

(n = 25) => 
{
  R = n => Math.random()*n | 0;
  N = _ => 'UDRLFB'[(r += 1+R(5)) % 6];
  r = 0;
  b = N();
  a = N();
  for(s = '' ; n; )
     c = N(),
     ~(a+b+c).search('^([UD]*|[RL]*|[FB]*)$')
       ? 0
       : s += (--n, a=b, b=c) + ["","'",2][R(3)];
  return s
}

Uji

var F=
(n=25,R=n=>Math.random()*n|0)=>(r=>{for(N=_=>'UDRLFB'[(r-=~R(5))%6],b=N(a=N(s=''));n;~(a+b+c).search('^([UD]*|[RL]*|[FB]*)$')?0:s+=(--n,a=b,b=c)+["","'",2][R(3)])c=N()})(0)||s

function go() {
  console.log(F(+M.value))
}

go()
Moves <input type=number min=1 id=M value=25 max=999>
<button onclick='go()'>Test</button>

edc65
sumber
2

Javascript - 112

for(c=b=j=25,r=Math.random;j;c+b-5|c-m&&b-m?document.write("URFBLD"[j--,c=b,b=m]+" 2'"[0|r()*3]+" "):0)m=0|r()*6
Mama Fun Roll
sumber
2

Java 8, 189 183 byte

v->{for(int i=26,n,m=0,r=0,s=0,t;i-->0;){for(n=m,t=1;t>0;t=m*n==9?1:0)m=(r=(int)(Math.random()*15))/3+1;s+=m;if(i<25)System.out.print("URFDLB".charAt(s%6)+(r%3<1?"'":r%3<2?"2":""));}}

Pelabuhan @LevelRiverSt 's C jawabannya . Saya mencoba beberapa hal sendiri, tetapi ini lebih pendek dari apa yang saya miliki ..

Cobalah online.

Kevin Cruijssen
sumber
2

Ruby , 116 107 105 95 byte

->{(0..r=l=m=24).map{m=rand 6while l==m||r/2==l/2&&l/2==m/2;r=l;l=m;'RLFBUD'[m]+" '2"[rand 3]}}

Cobalah online!

Asone Tuhid
sumber
1

Clojure, 223 byte

(let[R(range)F(fn[f p c](apply concat(filter f(partition-by p c))))](apply str(map str(take 25(F(fn[p](<(count p)3))(zipmap"UDLF""1122")(F(fn[p](=(count p)1))int(for[_ R](rand-nth"UDRLFB")))))(for[_ R](rand-nth[""\'\2])))))

Ini sangat bergantung pada pola "sequence -> partisi-by ->> - concat", ini digunakan untuk menyaring urutan wajah "ilegal". Seq ini kemudian dipetakan ke string bersamaan dengan postfix acak (termasuk string kosong).

Titik awal yang tidak disatukan:

(->> (for[_(range)](rand-nth"UDRLFB"))
     (partition-by int)           ; "identity" would be the correct fn to use here
     (filter(fn[p](=(count p)1))) ; Only one identical value in partition
     (apply concat)
     (partition-by(zipmap"UDLF""1122")) ; R & B are in the implicit nil group
     (filter(fn[p](<(count p)3)))       ; Only 1 or 2 consecutive faces from a group
     (apply concat)
     (take 25))
NikoNyrh
sumber