Python 2.7: 544 byte -50% = 272 byte **
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 mengganti tab dengan beberapa spasi putih. Jadi teknis versi ini memiliki 549 byte. Cukup ganti dua spasi pertama di baris 6-10 dengan tabulator.
Ide di balik program saya: Ide pertama saya adalah pencarian pertama yang menarik. Tapi ini terlalu lama. Sekitar 2 menit untuk perebutan keras (11 gerakan optimal). Jadi saya memutuskan untuk mendekati masalah dari kedua belah pihak. Saya menggunakan dua set. Saya menghasilkan semua negara secara berurutan dengan jarak 1,2,3, ... untuk mengacak dan menyimpannya di set1, dan pada saat yang sama semua negara dengan jarak 1,2,3, ... ke keadaan terpecahkan dan menyimpannya di set2. Pertama kali keadaan dalam kedua set, kami menemukan solusinya.
Untuk ini saya perlu warna kubus yang dipecahkan, yang tidak diketahui. Karakter 13, 20 dan 23 menentukan warna kiri, belakang dan bawah. Tetapi 3 warna ini cukup untuk mewakili kubus. Saya hanya mengganti 3 warna lainnya dengan spasi putih dan saya dapat mewakili kondisi terpecahkan saya sebagai '____ll____bbll____dddd'.
Oh, dan untuk memperpendek permutasi saya menggunakan ide dari /codegolf//a/34651/29577
Versi tidak disatukan:
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
Saya cukup senang dengan hasilnya, karena saya cukup baru di Python. Ini adalah salah satu program python pertama saya.
sunting: setengah tahun kemudian: 427 - 50% = 213.5
Punya sedikit lebih banyak pengalaman dalam Python dan golf. Jadi saya merevisi kode asli saya dan dapat menyimpan lebih dari 100 karakter.
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])
Saya pada dasarnya menggunakan pendekatan yang sama persis. Perubahan terbesar adalah, bahwa saya tidak mendefinisikan fungsi lagi. Dari pada
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)
dapat saya lakukan
for h in[0,1]*6:
for s in d[h]:
if s in d[1-h]:...
Saya juga mengubah langkah lamda sedikit. Pertama mempersingkat, dan kemudian mengintegrasikan kode secara langsung, karena panggilan fungsi hanya muncul sekali.
Saya menyimpan untuk setiap negara daftar angka antara 0 dan 11, untuk mewakili gerakan, bukan string yang berisi gerakan. Jumlahnya dikonversi pada bagian paling akhir.
Saya juga menggabungkan dua for-loop 'for k in r(3):for j in r(3):
menjadi satu for y in r(12)
. Karena itu saya juga harus melakukan gerakan U4, R4, F4
. Tentu saja langkah seperti itu tidak muncul dalam solusi terpendek, begitu " 2'"[x%4]
berhasil. (Jika x % 4 == 3
, akan ada indeks di luar rentang pengecualian)
Ini juga sedikit lebih cepat, karena saya mencari entri di set kedua sebelumnya. Sekitar 0,5 detik untuk solusi 11 langkah.