Python 1166 bayt
Okunabilirlik uğruna önemli miktarda boşluk bırakılmıştır. Boyut Bu boşluk kaldırma ve çeşitli girinti düzeylerini değiştirdikten sonra ölçülür Tab, Tab Space, Tab Tabayrıca çok büyük ölçüde performansını etkilemiş herhangi golf kaçınılmalıdır vb ben.
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
Örnek kullanım:
$ 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
Bu, her adım için çözmek üzere bir IDA * araması kullanan Thistlethwaite Algoritmasının bir uygulamasıdır. Tüm sezgisel tabloların anında hesaplanması gerektiğinden, genellikle bir sezgisel bulguyu iki veya daha fazla eşit büyüklükte parçalara bölen birkaç ödün verildi. Bu, sezgisel tabloların hesaplanmasını yüzlerce kez daha hızlı yapar, ancak arama aşamasını yavaşlatır, genellikle sadece hafifçe, ancak ilk küp durumuna bağlı olarak önemli olabilir.
Değişken Endeksi
T - ana sezgisel tablo.
S- çözülmüş bir küp hali. Her bir parça, bir karakter olarak temsil edilen bir bit maskesi olarak saklanır. Çözülmüş bir oryantasyon vektörü sıfır vektör olarak tanımlanır.
I - çeşitli bükülmeler, arama alanından kaldırılmaları sırasına göre.
G- Değiştirilebilecek çiftler olarak saklanan büküm permütasyon grupları. Sıkıştırılmış dizedeki her bayt bir çift için kodlar. Her bükümün altı adet değişimi gerekir: kenar döngüsü için üç ve köşe döngüsü için üç. Sıkıştırılmış dize yalnızca yazdırılabilir ascii içerir (karakter 32 - 126).
M - G. tarafından verilen bir hareket gerçekleştiren bir işlev
N - kodlama amacıyla dört nesnenin permütasyonunu sayıya dönüştürür.
H - T'den hareket derinliği ararken kullanılan küp durumu için sezgisel değeri hesaplar.
P - algoritmanın tek bir aşamasının tek bir derinliğinde bir arama yapın.
s - giriş küpünün permütasyon durumu.
o - giriş küpünün oryantasyon vektörü.
Verim
Tomas Rokicki'nin veri setini kullanarak , bu komut dosyası ortalamada 472ms (i5-3330 CPU @ 3.0 Ghz, PyPy 1.9.0) ile çözme başına ortalama 16.02 büküm (maksimum 35). Minimum çözülme süresi 233ms idi, maksimum 2.97s, standart sapma 0.488. Yarışmadaki puanlama kurallarını kullanarak (beyaz boşluk sayılmaz, anahtar kelimeler ve tanımlayıcılar 870 uzunluğunda bir bayt olarak sayılır), toplam puan 13.549 olur.
Son 46 vaka için (rastgele durumlar), ortalama 721 ms süre ile çözme başına ortalama 30.83 büküm.
Thistlethwaite Algoritması Üzerine Notlar
Thistlethwaite Algoritmasının uygulanmasını denemek isteyen herkesin yararına , işte kısa bir açıklama.
Algoritma çok basit bir çözüm alanı azaltma prensibi üzerinde çalışır. Yani, küpü çözmek için bir bükülme alt kümesinin gerekli olmadığı bir duruma düşürün, daha küçük bir çözelti alanına düşürün ve sonra kalan sadece birkaç bükülmeyi kullanarak geri kalanı çözün.
Thistlethwaite başlangıçta <L,R,F,B,U,D>→ <L,R,F,B,U2,D2>→ <L,R,F2,B2,U2,D2>→ önerdi <L2,R2,F2,B2,U2,D2>. Bununla birlikte, girdi formatı göz önüne alındığında, önce <L,R,F2,B2,U,D>(çeyrek tur Fya da değil B), sonra <L2,R2,F2,B2,U,D>da yarı dönüş durumuna ulaşmadan önce azaltmanın daha kolay olduğunu düşünüyorum . Bunun neden olduğunu tam olarak açıklamak yerine, her bir devlet için kriterleri belirledikten sonra açık olacağını düşünüyorum.
<L,R,F,B,U,D> ⇒ <L,R,F2,B2,U,D>
Dönüşleri ortadan kaldırmak Fve Bçeyreklik yapmak için yalnızca kenarların doğru yönlendirilmesi gerekir. Gilles Roux'un sitesinde 'doğru' ve 'yanlış' yönelimin ne olduğu hakkında çok iyi bir açıklaması var , bu yüzden onu açıklayacağım. Ama esas olarak, (bu giriş biçimi öylesine condusive neden ve bu Fve Başağıdaki regex eşleşirse bir kenar cubie doğru yöne, eleme): [^RL][^UD]. Doğru yönlendirme tipik olarak a ile işaretlenir 0ve ile yanlış 1. Temel olarak Uve Detiketler, yüzlerde veya yüzeyin üzerinde veya herhangi bir veya kenar kübün kenarlarında görünmeyebilir Rveya bir veyaLUDFB çeyrek büküm.
<L,R,F2,B2,U,D> ⇒ <L2,R2,F2,B2,U,D>
Burada iki kriter. İlk olarak, tüm köşeler doğru yönlendirilmiş olması gerekir, ve ikinci, ara tabaka cubies için her ( FR, FL, BR, BL) orta tabakada bir yerde olması gerekir. Bir köşe yönü, giriş formatı verilen çok basit bir şekilde tanımlanmıştır: birinci pozisyon Uveya D. Örneğin URB, yönlendirmeye 0(doğru yönlendirilmiş), LDFyönlendirmeye 1ve LFUyönlendirmeye sahiptir 2.
<L2,R2,F2,B2,U,D> ⇒ <L2,R2,F2,B2,U2,D2>
Buradaki kriterler aşağıdaki gibidir: her yüz yalnızca yüzünden veya doğrudan karşısındaki yüzden çıkartmalar içerebilir. Örneğin, Uyüzünde sadece Uve Dçıkartmalar Rolabilir , yüzünde sadece Rve Lçıkartmalar Folabilir , yüzünde sadece Fve Bçıkartmalar olabilir, vb. Bunu sağlamanın en kolay yolu, her kenar parçasının içeride olup olmadığını kontrol etmektir. 'dilim' ve 'yörüngesindeki' her köşe parçası. Ek olarak, bir kenar köşesi paritesine dikkat etmek gerekiyor. Her ne kadar, sadece köşe paritesini kontrol ediyorsanız, kenar paritesi de garanti edilir ve bunun tersi de geçerlidir.
Bükülmeler oryantasyonu nasıl etkiler?
Uve Dkatlanmış kenar yönünü de köşe yönünü de etkiler. Oryantasyon vektörünü güncellemeden parçalar doğrudan değiştirilebilir.
Rve Lkatlanmış kenar yönünü etkilemez, ancak köşe yönünü etkiliyor. Eğer döngüsünü nasıl tanımladığına bağlı olarak, köşe yönündeki değişim ya olacak +1, +2, +1, +2ya +2, +1, +2, +1, bütün modülo 3. R2Ve L2bükülmelerin köşe oryantasyonunu etkilemeyeceğini unutmayın , olduğu gibi +1+2sıfır modulo 3olduğu gibi +2+1.
Fve Bhem kenar oryantasyonlarını hem de köşe oryantasyonlarını etkiler. Kenar yönelimleri haline +1, +1, +1, +1(mod 2) ve köşe yönlendirmeleri aynıdır Rve L. Bunu unutmayın F2ve B2ne kenar yönlerini ne de köşe yönlerini etkilediğini unutmayın .