解决魔方


38

编写最短的程序,以在合理的时间范围内移动并解决Rubik的多维数据集(3 * 3 * 3)(例如,在您的计算机上最多5秒,而最多移动1000秒)。

输入的格式为:

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

(此特定输入表示已解决的多维数据集)。
前12个2个字符的字符串是UF,UR,... BL位置中的边(U =上,F =前,R =右,B =后,L =左,D =下),然后是下8个3个字符的字符串是UFR,URB,... DBR位置中的角。

输出应以这种格式给出一系列移动:

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

其中D1或D +代表将D(下)面顺时针旋转90度,L2代表将L面旋转180度,U3或U-代表将U面逆时针旋转90度。
字母不区分大小写,空格是可选的。

例如,上面的输出对于以下输入是正确的:

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

有关更多详细信息,请参阅Tomas Rokicki的多维数据集竞赛,除了计分将直接通过文件大小完成外,就像正常的打高尔夫球问题一样。还包括一个在线测试仪

供参考,最短的解决方案是多维数据集竞赛获奖者列表中的最后一个条目


对于那些努力使布局格式可视化的人:

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 ++ / Java / Perl / Python以外的语言?
Egor Skriptunoff 2013年

@EgorSkriptunoff在这里,可以使用任何您喜欢的东西,只是没有多维数据集求解库。
aditsu

那得分呢?通常的代码高尔夫得分(程序中的字节数)还是像2004年竞赛中那样的复杂得分?
Egor Skriptunoff

2
@jdstankosky,我添加了一个图表。
彼得·泰勒

7
我们可以拉开贴纸并四处移动吗?
Iszi 2013年

Answers:


25

C ++-1123

由于到目前为止还没有人发布任何答案,所以我决定简化并推广我的2004年解决方案。它仍然远远落后于我在问题中提到的最短的那个。

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

它不是随机的,但也不会直接进行。它先求解边缘,然后求解角。在每个步骤中,它尝试多达4种算法和简单的脸部转弯(依次而不是随机地)的各种组合,直到发现解决的部分数量有所改善,然后重复进行直到解决。它对边缘使用2种算法,对角使用2种算法,转换为所有立方体位置。

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

L2F3B2F3B1U3F1B3R2F3B1U3F1B3D2F2L3D2L1U2B1L1R3U2R1L3B1U2R1U2L1F1B3U2B1F3L1U2L3R1D3L1R3B2L3R1D3L1R3L3R1D3L1R3B2L3R1D3L1R3B3F1D3B1F3R2B3F1D3B1F3U2F3L3R1B3L1R3U2L3R1B3L1R3F1D2F1L1R3D2R1L3F1D2F3L2U1B1F3L2F1B3U1L2R3L1F3R1L3U2R3L1F3R1L3U1F2U1L1R3F2R1L3U1F2U3L3U3L1U3L3U2L1R1U1R3U1R1U2R3F3U3F1U3F3U2F1B1U1B3U1B1U2B3L1B3R3B1L3B3R1B1B3D3B1D3B3D2B1F1D1F3D1F1D2F3R1F3L3F1R3F3L1F1R3B3R1B3R3B2R1L1B1L3B1L1B2L3R1D3L3D1R3D3L1D1B3D3B1D3B3D2B1F1D1F3D1F1D2F3U3R3U1R3U3R2U1D1R1D3R1D1R2D3

(234移动,此处为0.3秒)


2
您知道什么...几秒钟内发布了另一个答案:)
aditsu

尽管这比Ruby解决方案要长,但我认为它“在合理的时间和动作范围内”更符合问题标准不过,我仍然希望看到一种解决方案,该解决方案的平均移动次数不到50个。
2013年

2
@primo谢谢:)我的原始代码平均进行了50次以上的操作,对于50次以下的操作,我认为您需要更多的(多维数据集)算法或其他方法,例如Thistlethwaite的方法。但是,效率(移动次数)与打高尔夫球不是很兼容。无论如何,要寻找替代解决方案,请查看Tomas Rokicki比赛的获胜者。
aditsu

23

Python 1166字节

为了便于阅读,留了相当数量的空格。大小删除此空白,并改变了各种各样的缩进水平之后测量TabTab SpaceTab Tab等我也避免了影响性能太大幅度的任何高尔夫球场。

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

用法示例:

$ 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

这是Thistlethwaite算法的一种实现,使用IDA *搜索来解决每个步骤。因为所有启发式表都需要即时计算,所以做出了一些折衷,通常将启发式分为两个或更多相等大小的部分。这使启发式表的计算速度提高了数百倍,同时减慢了搜索阶段,通常只是稍微慢了一点,但是根据初始多维数据集状态的不同,它可能很重要。

可变指数

  • T -主要的启发式表格。
  • S-解决的立方体状态。每个单独的片段都存储为位掩码,以字符表示。求解的方向矢量定义为零矢量。
  • I -各种曲折,以便从搜索空间中消除它们。
  • G-扭曲排列的组,存储为成对交换。压缩字符串中的每个字节编码一对。每个扭曲都需要进行六个交换:边缘循环三个,拐角循环三个。压缩的字符串仅包含可打印的ascii(字符32至126)。
  • M -执行移动的功能,由G给出。
  • N -将四个对象的排列转换为数字,以进行编码。
  • H -计算给定立方体状态的启发式值,用于从T查找移动深度。
  • P -在算法的单个阶段的单个深度执行搜索。
  • s -输入多维数据集的排列状态。
  • o -输入多维数据集的方向向量。

性能

使用Tomas Rokicki的数据集,此脚本平均每个求解平均16.02次扭曲(最多35次),平均时间为472ms(i5-3330 CPU @ 3.0 Ghz,PyPy 1.9.0)。最短求解时间为233ms,最大为2.97s,标准偏差为0.488。使用竞赛的评分准则(不计空格,关键字和标识符的长度为870计为一个字节),总得分将为13,549。

在最后46种情况下(随机状态),每个解算平均扭曲30.83次,平均时间为721ms。


关于Thistlethwaite算法的注释

为了使任何想尝试实现Thistlethwaite算法的人受益,这里有一个简短的解释。

该算法基于非常简单的解决方案空间缩减原理。也就是说,将立方体减少到不需要解决部分扭曲的状态,将其减少到较小的求解空间,然后仅使用剩余的少量扭曲即可解决其余部分。

西斯尔思韦原本建议<L,R,F,B,U,D>→交通<L,R,F,B,U2,D2>→交通<L,R,F2,B2,U2,D2>→交通<L2,R2,F2,B2,U2,D2>。但是,考虑到输入格式,我认为首先减小到<L,R,F2,B2,U,D>(没有四分之一圈FB),然后<L2,R2,F2,B2,U,D>在最终达到半圈状态之前比较容易。我认为没有定义确切的原因,而是在为每个州定义标准之后,这将是显而易见的。

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

为了消除FB直角转,只有边缘方向必须正确。吉尔斯·鲁(Gilles Roux)在他的网站上对“正确”和“不正确”的方向有很好的解释,所以我将解释留给他。但基本上,(这就是为什么这种输入格式如此易于使用FB消除的原因),如果边缘立方体与以下正则表达式匹配,则其方向正确[^RL][^UD]。正确的方向通常用表示,0不正确的用表示1。基本上,UD贴可能不会出现在RL面上,或者在任何UD边缘立方体的边缘上,或者在不要求F或的情况下不能将它们移动到位。B 四分之一转。

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

这里有两个标准。首先,所有的角部必须正确定向,并且第二,每个用于中间层cubies( ,FRFLBRBL必须在中间层中的某处。给定输入格式即可非常简单地定义转角方向:第一个U或的位置D。例如,URB具有方向0(正确定向),LDF具有方向1LFU具有方向2

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

这里的标准如下:每个面孔只能在其面孔或与之相对的面孔中包含贴纸。例如,在U脸上可能仅存在UD贴纸,在R脸上可能仅存在RL贴纸,在F脸上可能仅存在FB贴纸,等等。确保这一点的最简单方法是检查每个边缘块是否在它的“切片”,以及“轨道”中的每个角点。另外,需要注意边缘角平价。但是,如果仅检查转角奇偶校验,则也可以保证边缘奇偶校验,反之亦然。

扭曲如何影响方向

UD扭曲既不会影响边缘方向,也不会影响角方向。可以直接交换这些片段,而无需更新方向矢量。

RL扭曲不会影响边缘方向,但会影响角方向。根据定义循环的方式,拐角方向的更改将为+1, +2, +1, +2+2, +1, +2, +1,均为模3。需要注意的是R2L2波折不会影响到角落的方向,由于+1+2是零模3,因为是+2+1

F并同时B影响边缘方向和角方向。边的方向变为+1, +1, +1, +1(mod 2),角的方向与R和相同L。请注意,F2B2既不影响边缘取向,也不角落的方向。


很棒的文章。您听说过Kociemba的算法吗?
英里

我有。原则上,它是相同的算法,除了四个阶段,它只有两个:<L,R,F,B,U,D>-> <L2,R2,F2,B2,U,D>-> <I>。求解一个立方体最多需要29次扭曲(而不是Thistlethwaite的52次),但是它也需要非常大的查找表,这对于“即时”生成是不切实际的。
2013年

@ P0W输入格式有点混乱,我怀疑您那里可能有错误。我验证的每种情况都可以找到解决方案。
primo

@primo如果您有链接,您介意发布指向非高尔夫代码的链接吗?
Bilow

12

Ruby,742个字符

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}

上面的红宝石代码尚未完全使用。仍然有可能进一步改进代码(但作为入门者已经足够了)。

它逐层求解多维数据集,但不使用特定算法,而是执行随机的移动序列,直到多维数据集解决为止。

由于概率性质,有时可能需要5秒钟以上才能解决多维数据集,在极少数情况下,需要执行1000多次移动。

示例输出(对于输入“ RU LF UB DR DL BL UL FU BD RF BR FD LDF LBD FUL RFD UFR RDB UBL RBU”)为757移动:

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.gsub(/(.)\1*/){j=$&.size%4;$><<$1<<j<<' 'if j>0};o=z;s=t)if s>t

不错,但是有时我的计算机需要花费20秒钟以上的时间,在一种情况下,它需要48.7秒钟才能完成
aditsu

@aditsu是的。但这也很大程度上取决于您使用哪种红宝石解释器。在我的机器上,通常不到5秒。
2013年

我当前使用的是ruby 1.9.3_p392,它通常花费不到5秒的时间,但是我不能说“通常”
aditsu

尝试输入:FU FR RU BR DB LD LU LB LF RD DF BU FRU BUR FDR DLB DFL LUB FUL DBR
aditsu

一个要求:您可以将序列合并U1 U1 U1成一个序列U3吗?
2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.