Python 2.7 : 544 바이트 -50 % = 272 바이트 **
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는 탭을 여러 공백으로 바꿉니다. 기술적으로이 버전은 549 바이트입니다. 6-10 행의 처음 두 공백을 테이블로 바꾸십시오.
내 프로그램의 아이디어 : 나의 첫 번째 아이디어는 숨을 먼저 was는 것이었다. 그러나 이것은 너무 오래 걸렸습니다. 하드 (11 이동 최적) 스크램블의 경우 약 2 분. 그래서 나는 양쪽에서 문제에 접근하기로 결정했습니다. 나는 두 세트를 사용합니다. 1,2,3, ...의 거리를 스크램블까지 순차적으로 생성하고 set1에 저장하고, 1,2,3, ...의 모든 상태를 해결 된 상태로 저장하고 저장합니다 set2에서. 상태가 두 세트 모두에 처음있을 때 솔루션을 찾았습니다.
이를 위해 나는 해결되지 않은 큐브의 색상이 필요합니다. 문자 13, 20 및 23은 왼쪽, 뒤쪽 및 아래쪽 색상을 정의합니다. 그러나이 3 색은 큐브를 나타내는 데 충분합니다. 다른 3 색을 공백으로 바꾸면 해결 된 상태를 '____ll____bbll____dddd'로 나타낼 수 있습니다.
아, 그리고 순열을 줄이기 위해 /codegolf//a/34651/29577 의 아이디어를 사용했습니다.
언 골프 버전 :
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
파이썬에 익숙하지 않기 때문에 결과에 매우 만족합니다. 이것은 내 첫 번째 파이썬 프로그램 중 하나입니다.
편집 : 반 년 후 : 427-50 % = 213.5
파이썬과 골프에 대한 경험이 조금 더 있습니다. 그래서 나는 원래 코드를 수정했으며 100자를 초과 할 수 없었습니다.
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])
나는 기본적으로 똑같은 접근법을 사용합니다. 가장 큰 변화는 더 이상 함수를 정의하지 않는다는 것입니다. 대신에
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)
내가 할 수있는
for h in[0,1]*6:
for s in d[h]:
if s in d[1-h]:...
또한 이동 lamda를 약간 변경했습니다. 함수 호출은 한 번만 표시되므로 첫 번째 단축 및 코드를 직접 통합하십시오.
각 상태에 대해 이동을 포함하는 문자열 대신 이동을 나타내는 0과 11 사이의 숫자 목록을 유지합니다. 숫자는 맨 끝에 변환됩니다.
또한 두 개의 for-loop 'for k in r(3):for j in r(3):
를 하나로 결합했습니다 for y in r(12)
. 따라서 나는 또한 움직여야한다 U4, R4, F4
. 물론 그러한 움직임은 최단 솔루션에는 나타나지 않으므로 " 2'"[x%4]
작동합니다. (인 경우 x % 4 == 3
, 범위를 벗어난 색인 예외가있을 것입니다)
이전의 두 번째 세트에서 항목을 찾기 때문에 조금 더 빠릅니다. 11 이동 솔루션의 경우 약 0.5 초