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 thay thế các tab bằng nhiều khoảng trắng. Vì vậy, kỹ thuật phiên bản này có 549 byte. Chỉ cần thay thế hai khoảng trắng đầu tiên trong các dòng 6-10 bằng một bộ lập bảng.
Ý tưởng đằng sau chương trình của tôi: Ý tưởng đầu tiên của tôi là một cuộc tìm kiếm đầu tiên. Nhưng điều này mất quá nhiều thời gian. Khoảng 2 phút cho một cuộc tranh giành khó khăn (11 di chuyển tối ưu). Vì vậy, tôi quyết định tiếp cận vấn đề từ cả hai phía. Tôi sử dụng hai bộ. Tôi tạo tuần tự tất cả các trạng thái có khoảng cách 1,2,3, ... để tranh giành và lưu chúng trong tập 1, đồng thời tất cả các trạng thái có khoảng cách 1,2,3, ... đến trạng thái đã giải quyết và lưu chúng trong tập 2. Lần đầu tiên một trạng thái trong cả hai bộ, chúng tôi tìm thấy giải pháp.
Đối với điều này, tôi cần màu sắc của khối giải quyết, mà không được biết. Các ký tự 13, 20 và 23 xác định màu trái, lùi và xuống. Nhưng 3 màu này là đủ để đại diện cho khối. Tôi chỉ cần thay thế 3 màu còn lại bằng khoảng trắng và tôi có thể biểu thị trạng thái đã giải của mình là '____ll__bbll__dddd'.
Ồ, và để rút ngắn các hoán vị, tôi đã sử dụng một ý tưởng từ /codegolf//a/34651/29577
Phiên bản bị đánh cắp:
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
Tôi khá hài lòng với kết quả này, vì tôi khá mới với Python. Đây là một trong những chương trình trăn đầu tiên của tôi.
chỉnh sửa: nửa năm sau: 427 - 50% = 213,5
Có thêm một chút kinh nghiệm về Python và chơi gôn. Vì vậy, tôi đã sửa đổi mã gốc của mình và có thể lưu hơn 100 ký tự.
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])
Tôi về cơ bản sử dụng chính xác cùng một cách tiếp cận. Thay đổi lớn nhất là, tôi không định nghĩa một chức năng nữa. Thay vì
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)
tôi có thể làm
for h in[0,1]*6:
for s in d[h]:
if s in d[1-h]:...
Ngoài ra tôi đã thay đổi di chuyển lamda một chút. Trước tiên, sau đó tích hợp mã trực tiếp, vì lệnh gọi hàm chỉ xuất hiện một lần.
Tôi giữ cho mỗi trạng thái một danh sách các số từ 0 đến 11, để thể hiện các bước di chuyển, thay vì một chuỗi chứa các bước di chuyển. Các số được chuyển đổi vào cuối.
Ngoài ra tôi kết hợp hai vòng lặp for 'for k in r(3):for j in r(3):
thành một for y in r(12)
. Do đó tôi cũng phải thực hiện các động tác U4, R4, F4
. Tất nhiên một động thái như vậy không xuất hiện trong giải pháp ngắn nhất, vì vậy " 2'"[x%4]
hoạt động. (Nếu x % 4 == 3
, sẽ có một chỉ mục nằm ngoài phạm vi)
Nó cũng nhanh hơn một chút, vì tôi tìm mục trong tập thứ hai trước đó. Khoảng 0,5 giây cho một giải pháp di chuyển 11.