Python 2.7: 544 bayt -50% = 272 bayt **
import sys;o=''.join;r=range;a=sys.argv[1];a=o([(' ',x)[x in a[12]+a[19]+a[22]] for x in a]);v={a:''};w={' '*4+(a[12]*2+' '*4+a[19]*2)*2+a[22]*4:''}
m=lambda a,k:o([a[([0x55a5498531bb9ac58d10a98a4788e0,0xbdab49ca307b9ac2916a4a0e608c02,0xbd9109ca233beac5a92233a842b420][k]>>5*i)%32] for i in r(24)])
def z(d,h):
t={}
for s in d[0]:
if s in d[1]:print d[h][s]+d[1-h][s];exit()
n=[d[0][s],'']
for k in r(3):
for j in r(3):s=m(s,k);t[s]=n[h]+'RUF'[k]+" 2'"[(j,2-j)[h]]+n[1-h]
s=m(s,k)
d[0]=t;return d
while 1:v,w=z([v,w],0);w,v=z([w,v],1)
Stackexchange, sekmeleri birden çok boşlukla değiştirir. Çok teknik bu sürüm 549 bayt var. 6-10. Satırlardaki ilk iki boşluğu bir tablo ile değiştirin.
Programımın arkasındaki fikir: İlk fikrim ilk nefes aramasıydı. Ama bu çok uzun sürdü. Sert (11 hareket optimum) karıştırma için yaklaşık 2 dakika. Bu yüzden soruna her iki taraftan da yaklaşmaya karar verdim. İki set kullanıyorum. 1,2,3, ... mesafeli tüm durumları karıştırmaya ve set1'e kaydederim ve aynı zamanda 1,2,3, ... mesafeli tüm durumları çözülmüş haline getirir ve kaydederim set2. Bir durum her iki sette de ilk kez olduğunda çözümü bulduk.
Bunun için bilinmeyen çözülmüş küpün renklerine ihtiyacım var. 13, 20 ve 23 karakterleri sol, arka ve aşağı renkleri tanımlar. Ancak bu 3 renk küpü temsil etmek için yeterlidir. Diğer 3 rengi beyaz boşluklarla değiştiriyorum ve çözdüğüm durumu '____ll____bbll____dddd' olarak temsil edebilirim.
Oh, ve permütasyonları kısaltmak için /codegolf//a/34651/29577 adresinden bir fikir kullandım.
Ungolfed sürümü:
import sys
#define permutations for R,U,F
permutation = [[0,7,2,15,4,5,6,21,16,8,3,11,12,13,14,23,17,9,1,19,20,18,22,10],
[2,0,3,1,6,7,8,9,10,11,4,5,12,13,14,15,16,17,18,19,20,21,22,23],
[0,1,13,5,4,20,14,6,2,9,10,11,12,21,15,7,3,17,18,19,16,8,22,23]]
def applyMove(state, move):
return ''.join([state[i] for i in permutation[move]])
scramble = sys.argv[1]
#remove up,front,rigth colors
scramble = ''.join([(' ', x)[x in scramble[12]+scramble[19]+scramble[22]] for x in scramble])
solved = ' '*4+scramble[12]*2+' '*4+scramble[19]*2+scramble[12]*2+' '*4+scramble[19]*2+scramble[22]*4
dict1 = {scramble: ''} #stores states with dist 0,1,2,... from the scramble
dict2 = {solved: ''} #stores states with dist 0,1,2,... from the solved state
moveName = 'RUF'
turnName = " 2'"
for i in range(6):
tmp = {}
for state in dict1:
if state in dict2:
#solution found
print dict1[state] + dict2[state]
exit()
moveString = dict1[state]
#do all 9 moves
for move in range(3):
for turn in range(3):
state = applyMove(state, move)
tmp[state] = moveString + moveName[move] + turnName[turn]
state = applyMove(state, move)
dict1 = tmp
tmp = {}
for state in dict2:
if state in dict1:
#solution found
print dict1[state] + dict2[state]
exit()
moveString = dict2[state]
#do all 9 moves
for move in range(3):
for turn in range(3):
state = applyMove(state, move)
tmp[state] = moveName[move] + turnName[2 - turn] + moveString
state = applyMove(state, move)
dict2 = tmp
Sonuçtan oldukça memnunum, çünkü Python için oldukça yeniyim. Bu benim ilk python programlarımızdan biri.
düzenleme: yarım yıl sonra: 427 -% 50 = 213.5
Python ve golf alanında biraz daha deneyimim var. Bu yüzden orijinal kodumu gözden geçirdim ve 100'den fazla karakter kaydedebilirim.
import sys;o=''.join;a=sys.argv[1];d=[{o((' ',x)[x in a[12]+a[19]+a[22]]for x in a):[]},{' '*4+(a[12]*2+' '*4+a[19]*2)*2+a[22]*4:[]}]
for h in[0,1]*6:
for s,x in d[h].items():
for y in range(12):
d[h][s]=x+[y-[1,-1,1,3][h*y%4]];
if s in d[1-h]:print o('RUF'[x/4]+" 2'"[x%4]for x in d[0][s]+d[1][s][::-1]);exit()
s=o(s[ord(c)-97]for c in'acahabcdnpbfegefhugiovjgqkciljdeklflmmmnnvoopxphrqdjrrbsstttuuqsviwwwkxx'[y/4::3])
Temel olarak aynı yaklaşımı kullanıyorum. En büyük değişiklik, artık bir fonksiyon tanımlamam. Onun yerine
def z(d,h):
for s in d[0]:
if s in d[1]:...
while 1:v,w=z([v,w],0);w,v=z([w,v],1)
Yapabilirim
for h in[0,1]*6:
for s in d[h]:
if s in d[1-h]:...
Ayrıca hareket lamdasını biraz değiştirdim. İşlev çağrısı yalnızca bir kez göründüğünden, önce kısaltın ve sonra kodu doğrudan entegre edin.
Her durum için, hareketleri içeren bir dize yerine, hareketleri temsil etmek için 0 ile 11 arasında bir sayı listesi tutarım. Sayılar en sonunda dönüştürülür.
Ayrıca ı-döngüler iki Birleştirilen 'for k in r(3):for j in r(3):
birine for y in r(12)
. Bu nedenle hareketleri de yapmak zorundayım U4, R4, F4
. Tabii ki böyle bir hareket en kısa çözümde görünmüyor, bu yüzden " 2'"[x%4]
çalışıyor. (Eğer x % 4 == 3
aralık dışında istisna bir dizin olurdu)
Daha önce ikinci setteki girişi aradığım için biraz daha hızlı. 11 hareketli bir çözelti için yaklaşık 0.5 saniye.