Giải quyết khối Rubik


38

Viết chương trình ngắn nhất giải quyết khối Rubik (3 * 3 * 3) trong một khoảng thời gian và di chuyển hợp lý (giả sử, tối đa 5 giây trên máy của bạn và dưới 1000 lần di chuyển).

Đầu vào có định dạng:

UF UR UB UL DF DR DB DL FR FL BR BL UFR URB UBL ULF DRF DFL DLB DBR

(đầu vào cụ thể này đại diện cho khối đã giải quyết).
12 chuỗi 2 ký tự đầu tiên là các cạnh trong các vị trí UF, UR, ... BL (U = up, F = front, R = right, B = back, L = left, D = down), sau đó là 8 tiếp theo Chuỗi 3 ký tự là các góc trong các vị trí UFR, URB, ... DBR.

Đầu ra sẽ đưa ra một chuỗi các bước di chuyển trong định dạng này:

D+ L2 U+ F+ D+ L+ D+ F+ U- F+

Trong đó D1 hoặc D + đại diện cho việc xoay mặt D (xuống) theo chiều kim đồng hồ 90 độ, L2 là quay mặt L 180 độ, U3 hoặc U- đại diện cho quay mặt U ngược chiều kim đồng hồ 90 độ.
Thư không phân biệt chữ hoa chữ thường và dấu cách là tùy chọn.

Ví dụ, đầu ra ở trên là chính xác cho đầu vào sau:

RU LF UB DR DL BL UL FU BD RF BR FD LDF LBD FUL RFD UFR RDB UBL RBU

Để biết thêm chi tiết, vui lòng tham khảo cuộc thi lập phương của Tomas Rokicki , ngoại trừ việc ghi điểm sẽ được thực hiện trực tiếp theo kích thước tệp như một vấn đề đánh gôn mã thông thường. Một thử nghiệm trực tuyến được bao gồm quá.

Để tham khảo, giải pháp ngắn nhất đã được viết là mục cuối cùng trong danh sách người chiến thắng cuộc thi lập phương


Đối với những người đấu tranh để hình dung định dạng bố cục:

0-1 2-3 4-5 6-7 8-9 10-11 12-13 14-15 16-17 18-19 20-21 22-23 24-25-26 27-28-29 30-31-32 33-34-35 36-37-38 39-40-41 42-43-44 45-46-47
UF  UR  UB  UL  DF   DR    DB   DL    FR    FL     BR    BL     UFR      URB      UBL      ULF      DRF      DFL      DLB      DBR

Front:

                 +-------+-------+-------+
                /       /       /       /|
               /  30   /   4   /  27   / |
              +-------+-------+-------+  |
             /       /       /       /|28+
            /   6   /       /   2   / | /|
           +-------+-------+-------+  |/ |
          /       /       /       /|3 +  |
         /  33   /   0   /  24   / | /|21+
        +-------+-------+-------+  |/ | /|
        |       |       |       |26+  |/ |
        |  35   |   1   |   25  | /|  +  |
        |       |       |       |/ | /|47+
        +-------+-------+-------+  |/ | /
        |       |       |       |17+  |/
        |  18   |       |  16   | /|11+
        |       |       |       |/ | /
        +-------+-------+-------+  |/
        |       |       |       |37+
        |  40   |   9   |  38   | /
        |       |       |       |/
        +-------+-------+-------+


Hidden faces:

                 +-------+-------+-------+
                /|       |       |       |
               / |  31   |   5   |  29   |
              +  |       |       |       |
             /|32+-------+-------+-------+
            / | /|       |       |       |
           +  |/ |  22   |       |  20   |
          /|7 +  |       |       |       |
         / | /|23+-------+-------+-------+
        +  |/ | /|       |       |       |
        |34+  |/ |  44   |  13   |  46   |
        | /|  +  |       |       |       |
        |/ | /|43+-------+-------+-------+
        +  |/ | /       /       /       /
        |19+  |/  42   /  12   /  45   /
        | /|15+-------+-------+-------+
        |/ | /       /       /       /
        +  |/  14   /       /  10   /
        |41+-------+-------+-------+
        | /       /       /       /
        |/  39   /   8   /   36  /
        +-------+-------+-------+

3
Các ngôn ngữ khác ngoài C / C ++ / Java / Perl / Python có được chấp nhận không?
Egor Skriptunoff

@EgorSkriptunoff Ở đây có, sử dụng bất cứ thứ gì bạn thích, chỉ cần không có thư viện giải khối.
aditsu

Còn việc ghi bàn thì sao? Điểm đánh gôn thông thường (byte trong chương trình) hoặc chấm điểm phức tạp như trong cuộc thi năm 2004?
Egor Skriptunoff

2
@jdstankosky, tôi đã thêm một sơ đồ.
Peter Taylor

7
Chúng ta có được phép gỡ bỏ các nhãn dán và di chuyển chúng xung quanh không?
Iszi

Câu trả lời:


25

C ++ - 1123

Vì không ai đăng bất kỳ câu trả lời nào cho đến nay, tôi quyết định đơn giản hóa và đánh golf giải pháp năm 2004 của tôi. Nó vẫn còn thua xa câu hỏi ngắn nhất mà tôi đã đề cập trong câu hỏi.

#include<iostream>
#include<vector>
#define G(i,x,y)for(int i=x;i^y;i++)
#define h(x)s[a[x]/q*q+(a[x]+j)%q-42]
#define B(x)D=x;E=O.substr(j*3,3);G(i,0,3)E+=F[5-F.find(E[2-i])];G(i,0,D.length())D[i]=E[F.find(D[i++])];m.push_back(D);
#define P(a,b)G(i,0,6)G(k,49,52){e[0]=F[i];e[1]=k;m.push_back(e);}G(j,0,24){B(a)B(b)}
#define T C();z=m.size();for(b=c;b;){d=s;G(i,o=w=1,4){w*=z;if(o)G(j,0,w)if(o){s=d;u=j;G(k,0,i){f=m[u%z];G(x,0,f.length()){a=M[F.find(f[x++])];G(i,0,f[x]-48)G(l,0,2){q=3-l;p=4*l;G(j,0,q){t=h(p+3);G(k,-3,0)h(p-k)=h(p-1-k);h(p)=t;}}}u/=z;}C();if(c<b){u=j;G(k,0,i){std::cout<<m[u%z];u/=z;}b=c;o=0;}}}}
std::string s,a,D,E,d,f,e="  ",S="UFURUBULDFDRDBDLFRFLBRBLUFRURBUBLULFDRFDFLDLBDBR",F="ULFBRD",M[]={"KHEB*0.,","KRTI0<8@","KDNS*;2=","IVXG/@7>","BGWP,>4:","QNWT2468"},O=S.substr(24)+"FDRFRUFULFLDRDBRBURUFRFDBDLBLUBURBRDLDFLFULUBLBD";std::vector<std::string>m;int
w,X=8,Y=16,o,c,u,b,z,p,q,t;void C(){c=0;G(i,X,Y)c+=s[i]!=S[i];}main(int
g,char**v){G(i,1,g)s+=v[i];P("U2F1R1L3U2L1R3F1U2","L3R1F3L1R3D2L3R1F3L1R3");T;Y=24;T;X=0;T;m.clear();P("R3D3R1D3R3D2R1L1D1L3D1L1D2L3","R1F3L3F1R3F3L1F1");G(I,5,9){Y=I*6;T}}

Nó không ngẫu nhiên, nhưng nó cũng không tiến hành đơn giản. Nó giải quyết các cạnh đầu tiên, sau đó các góc. Ở mỗi bước, nó thử kết hợp nhiều thuật toán khác nhau với tối đa 4 thuật toán và quay mặt đơn giản (tuần tự, không ngẫu nhiên), cho đến khi tìm thấy sự cải thiện về số lượng các mảnh đã giải, sau đó lặp lại cho đến khi giải được. Nó sử dụng 2 thuật toán cho các cạnh và 2 cho các góc, được dịch sang tất cả các vị trí khối.

Ví dụ đầu ra cho RU LF UB DR DL BL UL FU BD RF BR FD LDF LBD FUL RFD UFR RDB UBL RBU:

L2F3B2F3B1U3F1B3R2F3B1U3F1B3D2F2L3D2L1U2B1L1R3U2R1L3B1U2R1U2L1F1B3U2B1F3L1U2L3R1D3L1R3B2L3R1D3L1R3L3R1D3L1R3B2L3R1D3L1R3B3F1D3B1F3R2B3F1D3B1F3U2F3L3R1B3L1R3U2L3R1B3L1R3F1D2F1L1R3D2R1L3F1D2F3L2U1B1F3L2F1B3U1L2R3L1F3R1L3U2R3L1F3R1L3U1F2U1L1R3F2R1L3U1F2U3L3U3L1U3L3U2L1R1U1R3U1R1U2R3F3U3F1U3F3U2F1B1U1B3U1B1U2B3L1B3R3B1L3B3R1B1B3D3B1D3B3D2B1F1D1F3D1F1D2F3R1F3L3F1R3F3L1F1R3B3R1B3R3B2R1L1B1L3B1L1B2L3R1D3L3D1R3D3L1D1B3D3B1D3B3D2B1F1D1F3D1F1D2F3U3R3U1R3U3R2U1D1R1D3R1D1R2D3

(234 di chuyển, 0,3 giây tại đây)


2
Bạn biết gì ... một câu trả lời khác đã được đăng trong vài giây :)
aditsu

Mặc dù điều này dài hơn giải pháp Ruby, tôi cảm thấy rằng nó phù hợp hơn với tiêu chí vấn đề "trong một khoảng thời gian hợp lý và di chuyển." Tuy nhiên, tôi vẫn muốn xem một giải pháp trung bình dưới ~ 50 di chuyển.
Primo

2
@primo Cảm ơn :) Mã ban đầu của tôi trung bình trên 50 lần di chuyển, dưới 50 tuổi tôi nghĩ bạn cần nhiều thuật toán (khối) hơn hoặc một cách tiếp cận khác như phương pháp của Thistlethwaite. Tuy nhiên, hiệu quả (trong số các động tác) không tương thích lắm với việc chơi golf. Dù sao, để biết các giải pháp thay thế, hãy kiểm tra những người chiến thắng trong cuộc thi của Tomas Rokicki.
aditsu

23

Python 1166 byte

Một lượng đáng kể khoảng trắng đã được để lại cho mục đích dễ đọc. Kích thước được đo sau khi loại bỏ khoảng trắng này, và thay đổi mức độ thụt đầu dòng khác nhau để Tab, Tab Space, Tab Tab, vv Tôi cũng đã tránh được bất kỳ chơi golf mà ảnh hưởng đến hiệu suất quá quyết liệt.

T=[]
S=[0]*20,'QTRXadbhEIFJUVZYeijf',0
I='FBRLUD'

G=[(~i%8,i/8-4)for i in map(ord,'ouf|/[bPcU`Dkqbx-Y:(+=P4cyrh=I;-(:R6')]
R=range

def M(o,s,p):
 z=~p/2%-3;k=1
 for i,j in G[p::6]:i*=k;j*=k;o[i],o[j]=o[j]-z,o[i]+z;s[i],s[j]=s[j],s[i];k=-k

N=lambda p:sum([i<<i for i in R(4)for j in R(i)if p[j]<p[i]])

def H(i,t,s,n=0,d=()):
 if i>4:n=N(s[2-i::2]+s[7+i::2])*84+N(s[i&1::2])*6+divmod(N(s[8:]),24)[i&1]
 elif i>3:
  for j in s:l='UZifVYje'.find(j);t[l]=i;d+=(l-4,)[l<4:];n-=~i<<i;i+=l<4
  n+=N([t[j]^t[d[3]]for j in d])
 elif i>1:
  for j in s:n+=n+[j<'K',j in'QRab'][i&1]
 for j in t[13*i:][:11]:n+=j%(2+i)-n*~i
 return n

def P(i,m,t,s,l=''):
 for j in~-i,i:
  if T[j][H(j,t,s)]<m:return
 if~m<0:print l;return t,s
 for p in R(6):
  u=t[:];v=s[:]
  for n in 1,2,3:
   M(u,v,p);r=p<n%2*i or P(i,m+1,u,v,l+I[p]+`n`)
   if r>1:return r

s=raw_input().split()
o=[-(p[-1]in'UD')or p[0]in'RL'or p[1]in'UD'for p in s]
s=[chr(64+sum(1<<I.find(a)for a in x))for x in s]

for i in R(7):
 m=0;C={};T+=C,;x=[S]
 for j,k,d in x:
  h=H(i,j,k)
  for p in R(C.get(h,6)):
   C[h]=d;u=j[:];v=list(k)
   for n in i,0,i:M(u,v,p);x+=[(u[:],v[:],d-1)]*(p|1>n)
 if~i&1:
  while[]>d:d=P(i,m,o,s);m-=1
  o,s=d

Sử dụng mẫu:

$ more in.dat
RU LF UB DR DL BL UL FU BD RF BR FD LDF LBD FUL RFD UFR RDB UBL RBU

$ pypy rubiks.py < in.dat
F3R1U3D3B1
F2R1F2R3F2U1R1L1
R2U3F2U3F2U1R2U3R2U1
F2L2B2R2U2L2D2L2F2

Đây là một triển khai của Thuật toán của Thistlethwaite, sử dụng tìm kiếm IDA * để giải quyết cho từng bước. Bởi vì tất cả các bảng heuristic cần phải được tính toán một cách nhanh chóng, một số thỏa hiệp đã được thực hiện, thường phá vỡ một heuristic thành hai hoặc nhiều phần có kích thước khá bằng nhau. Điều này làm cho việc tính toán các bảng heuristic nhanh hơn hàng trăm lần, trong khi làm chậm giai đoạn tìm kiếm, thường chỉ một chút, nhưng nó có thể có ý nghĩa tùy thuộc vào trạng thái khối ban đầu.

Chỉ số biến

  • T - bảng heuristic chính.
  • S- một trạng thái khối giải quyết. Mỗi mảnh riêng lẻ được lưu trữ dưới dạng một mặt nạ bit, được biểu diễn dưới dạng một ký tự. Một vectơ định hướng được giải được định nghĩa là vectơ không.
  • I - các vòng xoắn khác nhau, theo thứ tự mà chúng bị loại khỏi không gian tìm kiếm.
  • G- các nhóm cho hoán vị xoắn, được lưu trữ dưới dạng cặp được hoán đổi. Mỗi byte trong chuỗi nén mã hóa cho một cặp. Mỗi vòng xoắn cần sáu lần hoán đổi: ba cho chu kỳ cạnh và ba cho chu kỳ góc. Chuỗi nén chỉ chứa ascii có thể in (char 32 đến 126).
  • M - một chức năng thực hiện di chuyển, được đưa ra bởi G.
  • N - chuyển đổi một hoán vị của bốn đối tượng thành một số, cho mục đích mã hóa.
  • H - tính giá trị heuristic cho trạng thái khối đã cho, được sử dụng để tra cứu độ sâu di chuyển từ T.
  • P - thực hiện tìm kiếm ở một độ sâu duy nhất của một pha của thuật toán.
  • s - trạng thái hoán vị của khối đầu vào.
  • o - vector định hướng của khối đầu vào.

Hiệu suất

Sử dụng bộ dữ liệu của Tomas Rokicki , tập lệnh này trung bình 16,02 vòng xoắn cho mỗi lần giải (tối đa 35), với thời gian trung bình là 472ms (i5-3330 CPU @ 3.0 Ghz, PyPy 1.9.0). Thời gian giải tối thiểu là 233ms với tối đa 2,97 giây, độ lệch chuẩn 0,488. Sử dụng hướng dẫn chấm điểm từ cuộc thi (không được tính khoảng trắng, từ khóa và số nhận dạng được tính là một byte cho độ dài 870), tổng điểm sẽ là 13,549.

Đối với 46 trường hợp cuối cùng (các trạng thái ngẫu nhiên), trung bình 30,83 vòng xoắn cho mỗi lần giải, với thời gian trung bình là 721ms.


Ghi chú về Thuật toán của Thistlethwaite

Vì lợi ích của bất kỳ ai muốn thử triển khai Thuật toán của Thistlethwaite , đây là một lời giải thích ngắn gọn.

Thuật toán hoạt động trên nguyên tắc giảm không gian giải pháp rất đơn giản. Đó là, giảm khối lập phương xuống trạng thái trong đó một tập hợp xoắn không cần thiết để giải quyết nó, giảm nó xuống một không gian giải pháp nhỏ hơn và sau đó giải quyết phần còn lại chỉ sử dụng một vài vòng xoắn còn lại.

Thistlethwaite ban đầu đề xuất <L,R,F,B,U,D><L,R,F,B,U2,D2><L,R,F2,B2,U2,D2><L2,R2,F2,B2,U2,D2>. Tuy nhiên, với định dạng đầu vào, tôi nghĩ việc giảm đầu tiên dễ dàng hơn <L,R,F2,B2,U,D>(không quay đầu quý Fhoặc B), và sau đó <L2,R2,F2,B2,U,D>trước khi đạt đến trạng thái nửa lượt. Thay vì giải thích chính xác lý do tại sao, tôi nghĩ nó sẽ rõ ràng sau khi xác định các tiêu chí cho từng tiểu bang.

<L,R,F,B,U,D><L,R,F2,B2,U,D>

Để loại bỏ FBlượt quý, chỉ các cạnh phải được định hướng chính xác. Gilles Roux có một lời giải thích rất hay trên trang web của mình về định hướng 'chính xác' và 'không chính xác' là gì, vì vậy tôi sẽ để lại lời giải thích cho anh ấy. Nhưng về cơ bản, (và đây là lý do tại sao định dạng đầu vào này rất thuận lợi FBloại bỏ), một hình khối cạnh được định hướng chính xác nếu nó phù hợp với biểu thức chính thức sau : [^RL][^UD]. Một định hướng đúng thường được biểu thị bằng một 0và không chính xác với 1. Về cơ bản UDnhãn dán có thể không xuất hiện trên Rhoặc Lmặt, hoặc trên các cạnh của bất kỳ Uhoặc các hình khối Dcạnh, hoặc chúng không thể được di chuyển vào vị trí mà không yêu cầu một FhoặcB xoắn quý.

<L,R,F2,B2,U,D><L2,R2,F2,B2,U,D>

Hai tiêu chí ở đây. Thứ nhất, tất cả các góc phải được định hướng một cách chính xác, và thứ hai, mỗi cho cubies lớp giữa ( FR, FL, BR, BL) phải ở đâu đó trong lớp trung lưu. Định hướng góc được xác định rất đơn giản với định dạng đầu vào: vị trí của đầu tiên Uhoặc D. Ví dụ: URBcó định hướng 0( định hướng chính xác), LDFcó định hướng 1LFUcó định hướng 2.

<L2,R2,F2,B2,U,D><L2,R2,F2,B2,U2,D2>

Các tiêu chí ở đây là như sau: mỗi khuôn mặt chỉ có thể chứa nhãn dán từ mặt của nó hoặc từ mặt đối diện trực tiếp với nó. Ví dụ, trên Umặt chỉ có thể có UDdán, trên Rmặt chỉ có thể có RLdán, trên Fmặt chỉ có thể có FBdán, v.v ... Cách dễ nhất để đảm bảo điều này là kiểm tra xem mỗi mảnh cạnh có ở trong không 'lát cắt' và mỗi mảnh góc trong 'quỹ đạo' của nó. Ngoài ra, người ta cần chú ý đến tính chẵn lẻ góc. Mặc dù, nếu bạn chỉ kiểm tra tính chẵn lẻ góc, tính chẵn lẻ cạnh cũng được đảm bảo và ngược lại.

Xoắn ảnh hưởng đến định hướng như thế nào

UDxoắn không ảnh hưởng đến hướng cạnh, cũng không phải hướng góc. Các mảnh có thể được hoán đổi trực tiếp mà không cần cập nhật vectơ định hướng.

RLxoắn không ảnh hưởng đến hướng cạnh, nhưng chúng ảnh hưởng đến hướng góc. Tùy thuộc vào cách bạn xác định chu kỳ của mình, sự thay đổi trong hướng góc sẽ là +1, +2, +1, +2hoặc +2, +1, +2, +1, tất cả là modulo 3. Lưu ý rằng R2L2xoắn không ảnh hưởng đến hướng góc, như +1+2là không modulo 3, như là +2+1.

FBảnh hưởng đến cả định hướng cạnh và định hướng góc. Định hướng cạnh trở thành +1, +1, +1, +1(mod 2) và định hướng góc giống như cho RL. Lưu ý rằng F2B2ảnh hưởng đến cả định hướng cạnh, cũng không phải định hướng góc.


Tuyệt vời viết. Bạn đã nghe nói về thuật toán của Kociemba chưa?
dặm

Tôi có. Về nguyên tắc, đó là cùng một thuật toán, ngoại trừ thay vì bốn giai đoạn, nó chỉ có hai giai đoạn: <L,R,F,B,U,D>-> <L2,R2,F2,B2,U,D>-> <I>. Nó đòi hỏi tối đa 29 vòng xoắn để giải một khối lập phương (thay vì 52 cho Thistlethwaite), nhưng nó cũng đòi hỏi các bảng tra cứu rất lớn, sẽ không thực tế để tạo ra 'trên đường bay'.
Primo

@ P0W định dạng đầu vào hơi khó hiểu, tôi nghi ngờ bạn có thể có lỗi ở đó. Mỗi trường hợp tôi đã xác minh kết quả trong một giải pháp.
primo

@primo Bạn có phiền khi xuất bản một liên kết đến mã không chơi gôn nếu bạn có nó không?
Bilow

12

Ruby, 742 ký tự

r=->y{y.split.map{|x|[*x.chars]}}
G=r['UF UR UB UL DF DR DB DL FR FL BR BL UFR URB UBL ULF DRF DFL DLB DBR']
o=r[gets]
x=[];[[%w{U UU UUU L LL LLL}+D=%w{D DD DDD},0],[%w{FDFFF RFDFFFRRR}+D,12],[%w{DDDRRRDRDFDDDFFF DLDDDLLLDDDFFFDF}+D,8],[%w{DFLDLLLDDDFFF RDUUUFDUUULDUUUBDUUU}+D,4],[%w{LDDDRRRDLLLDDDRD RRRDLDDDRDLLLDDD LFFFLLLFLFFFLLLF},16]].map{|q,y|x+=[*y..y+3]
3.times{q.map{|e|q|=[e.tr('LFRB','FRBL')]}}
w=->u{x.count{|t|u[t]!=G[t]}}
s=w[o]
(c=(0..rand(12)).map{q.sample}*''
z=o
c.chars{|m|z="=$'*:036\".?BOHKVGRWZ!$@*-0C69<4(E\\INQTMX!$'B-03<9*?6EHYLQPUZ!9'*-?360<$BSFKN[TWJ$'*!-0369<?BHKNEQTWZ!$'*6-039<?BEHKNTWZQ"[20*('FBLRUD'=~/#{m}/),20].bytes.map{|e|z[e/3-11].rotate e%3}}
t=w[z]
(c.chars{|e|$><<e<<'1 '};o=z;s=t)if s>t
)until s<1}

Mã ruby ​​ở trên chưa được đánh golf đầy đủ. Vẫn có khả năng cải thiện mã hơn nữa (nhưng nó đã đủ để bắt đầu).

Nó giải quyết lớp khối theo từng lớp nhưng không sử dụng thuật toán cụ thể mà thay vào đó thực hiện các chuỗi di chuyển ngẫu nhiên cho đến khi khối được giải quyết.

Do tính chất xác suất, đôi khi có thể mất hơn 5 giây để giải khối lập phương và trong những trường hợp hiếm hoi phải mất hơn 1000 lần di chuyển.

Đầu ra ví dụ (đối với đầu vào 'RU LF UB DR DL BL UL FU BD RF BR FD LDF LBD FUL RFD UFR RDB UBL RBU') là 757 di chuyển:

F1 R1 R1 F1 F1 F1 R1 R1 R1 L1 L1 L1 F1 D1 L1 L1 D1 D1 D1 D1 L1 B1 D1 
B1 B1 B1 L1 L1 L1 F1 D1 F1 F1 F1 L1 D1 L1 L1 L1 B1 D1 B1 B1 B1 R1 D1 
R1 R1 R1 L1 B1 D1 B1 B1 B1 L1 L1 L1 D1 D1 B1 D1 B1 B1 B1 B1 D1 B1 B1 
B1 L1 D1 L1 L1 L1 D1 D1 D1 D1 D1 R1 D1 R1 R1 R1 R1 F1 D1 F1 F1 F1 R1 
R1 R1 R1 D1 R1 R1 R1 F1 L1 D1 L1 L1 L1 F1 F1 F1 D1 D1 D1 D1 L1 D1 L1 
L1 L1 F1 L1 D1 L1 L1 L1 F1 F1 F1 D1 D1 L1 D1 L1 L1 L1 D1 L1 D1 L1 L1 
L1 L1 D1 L1 L1 L1 D1 R1 D1 D1 D1 R1 R1 R1 D1 D1 D1 B1 B1 B1 D1 B1 D1 
L1 D1 D1 D1 L1 L1 L1 D1 D1 D1 F1 F1 F1 D1 F1 D1 D1 D1 B1 B1 B1 D1 B1 
D1 R1 D1 D1 D1 R1 R1 R1 D1 D1 D1 B1 B1 B1 D1 B1 D1 R1 D1 D1 D1 R1 R1 
R1 D1 B1 D1 D1 D1 B1 B1 B1 D1 D1 D1 L1 L1 L1 D1 L1 D1 B1 D1 D1 D1 B1 
B1 B1 D1 D1 D1 L1 L1 L1 D1 L1 D1 D1 F1 D1 D1 D1 F1 F1 F1 D1 D1 D1 R1 
R1 R1 D1 R1 D1 D1 D1 R1 R1 R1 D1 R1 D1 F1 D1 D1 D1 F1 F1 F1 D1 B1 D1 
D1 D1 B1 B1 B1 D1 D1 D1 L1 L1 L1 D1 L1 D1 D1 D1 F1 F1 F1 D1 F1 D1 L1 
D1 D1 D1 L1 L1 L1 D1 D1 D1 D1 D1 D1 F1 F1 F1 D1 F1 D1 L1 D1 D1 D1 L1 
L1 L1 D1 D1 D1 F1 F1 F1 D1 F1 D1 L1 D1 D1 D1 L1 L1 L1 D1 F1 D1 D1 D1 
F1 F1 F1 D1 D1 D1 R1 R1 R1 D1 R1 D1 D1 D1 F1 F1 F1 D1 F1 D1 L1 D1 D1 
D1 L1 L1 L1 D1 D1 D1 F1 F1 F1 D1 F1 D1 L1 D1 D1 D1 L1 L1 L1 D1 D1 D1 
D1 D1 F1 F1 F1 D1 F1 D1 L1 D1 D1 D1 L1 L1 L1 D1 D1 D1 D1 D1 D1 R1 F1 
D1 F1 F1 F1 D1 D1 D1 R1 R1 R1 D1 F1 L1 D1 L1 L1 L1 D1 D1 D1 F1 F1 F1 
D1 B1 R1 D1 R1 R1 R1 D1 D1 D1 B1 B1 B1 D1 B1 R1 D1 R1 R1 R1 D1 D1 D1 
B1 B1 B1 D1 D1 D1 D1 B1 R1 D1 R1 R1 R1 D1 D1 D1 B1 B1 B1 D1 D1 D1 D1 
D1 D1 B1 B1 B1 D1 F1 D1 D1 D1 B1 D1 F1 F1 F1 D1 D1 D1 R1 R1 R1 D1 L1 
D1 D1 D1 R1 D1 L1 L1 L1 D1 D1 D1 B1 D1 D1 D1 F1 F1 F1 D1 B1 B1 B1 D1 
D1 D1 F1 D1 B1 B1 B1 D1 F1 D1 D1 D1 B1 D1 F1 F1 F1 D1 D1 D1 L1 D1 D1 
D1 R1 R1 R1 D1 L1 L1 L1 D1 D1 D1 R1 D1 F1 R1 R1 R1 F1 F1 F1 R1 F1 R1 
R1 R1 F1 F1 F1 R1 R1 R1 R1 D1 L1 D1 D1 D1 R1 D1 L1 L1 L1 D1 D1 D1 B1 
B1 B1 D1 F1 D1 D1 D1 B1 D1 F1 F1 F1 D1 D1 D1 F1 R1 R1 R1 F1 F1 F1 R1 
F1 R1 R1 R1 F1 F1 F1 R1 F1 D1 D1 D1 B1 B1 B1 D1 F1 F1 F1 D1 D1 D1 B1 
D1 F1 R1 R1 R1 F1 F1 F1 R1 F1 R1 R1 R1 F1 F1 F1 R1 F1 F1 F1 D1 B1 D1 
D1 D1 F1 D1 B1 B1 B1 D1 D1 D1 R1 D1 D1 D1 L1 L1 L1 D1 R1 R1 R1 D1 D1 
D1 L1 D1 R1 R1 R1 D1 L1 D1 D1 D1 R1 D1 L1 L1 L1 D1 D1 D1 R1 D1 D1 D1 
L1 L1 L1 D1 R1 R1 R1 D1 D1 D1 L1 D1 F1 F1 F1 D1 B1 D1 D1 D1 F1 D1 B1 
B1 B1 D1 D1 D1 L1 L1 L1 D1 R1 D1 D1 D1 L1 D1 R1 R1 R1 D1 D1 D1 

Có thể giảm số lần di chuyển đáng kể nếu các di chuyển tương tự được nhóm lại với nhau. Do đó, người ta có thể thay thế đầu ra như

(c.gsub(/(.)\1*/){j=$&.size%4;$><<$1<<j<<' 'if j>0};o=z;s=t)if s>t

Đẹp, nhưng đôi khi phải mất hơn 20 giây trên máy tính của tôi, trong một trường hợp, nó đã hoàn thành trong 48,7 giây
aditsu

@aditsu Vâng. Nhưng nó cũng mạnh mẽ phụ thuộc vào trình thông dịch ruby ​​mà bạn sử dụng. Trên máy của tôi thường mất ít hơn 5 giây.
Howard

Tôi hiện đang sử dụng ruby 1.9.3_p392, thường mất ít hơn 5 giây nhưng tôi không thể nói "thông thường"
aditsu

Hãy thử đầu vào này:FU FR RU BR DB LD LU LB LF RD DF BU FRU BUR FDR DLB DFL LUB FUL DBR
aditsu

Một yêu cầu: bạn có thể hợp nhất các chuỗi như U1 U1 U1thành một U3không?
Primo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.