Python - 1669
ยังค่อนข้างยาว แต่เร็วพอที่จะเรียกใช้ตัวอย่างล่าสุดได้ในไม่กี่วินาทีบนคอมพิวเตอร์ของฉัน อาจเป็นไปได้ที่จะทำให้ความเร็วในการใช้งานสั้นลง แต่ตอนนี้มันใกล้เคียงกับโค้ดที่ไม่ได้รับการดัดแปลง
ตัวอย่างผลลัพธ์สำหรับกรณีทดสอบล่าสุด:
0 11 1 11 2 11 3 11 4 11 4 10 3 10 2 10 1 10 1 9 2 9 3 9 4 9 4 8 3 8 3 7 4 7 5 7 5 6 5 5 6 5 6 6 6 7 7 7 8 7 8 8 7 8 6 8 5 8 5 9 5 10 5 11 6 11 6 10 6 9 7 9 8 9 8 10 7 10 7 11 8 11 9 11 9 10 9 9 10 9 10 10 10 11 11 11 11 10 11 9 11 8 11 7 10 7 10 8 9 8 9 7 9 6 10 6 11 6 11 5 11 4 11 3 10 3 9 3 9 4 9 5 8 5 8 4 8 3 8 2 8 1 9 1 10 1 10 0 9 0 8 0 7 0 7 1 7 2 6 2 5 2 5 1 6 1 6 0 5 0 4 0 3 0 2 0 2 1 3 1 4 1 4 2 4 3 5 3 6 3 7 3 7 4 6 4 5 4 4 4 4 5 4 6 3 6 3 5 3 4 3 3 3 2 2 2 2 3 1 3 1 2 1 1 1 0 0 0 0 1 0 2 0 3 0 4 0 5 0 6 1 6 1 5 1 4 2 4 2 5 2 6 2 7 1 7 1 8 0 8 0 9 0 10
รหัส:
I=raw_input().split('\n');X=len(I[0]);Y=len(I);R=range
def S(g=0,c=0,x=0,y=0):
if y>=Y:return 0
if g==0:g=[[-1]*X for i in R(Y)];c=[[-1]*X for i in R(Y)]
o={'.':set(R(7)),'w':{1,2},'b':{3,4,5,6}}[I[y][x]].copy()
o&={0,1,3,4}if y<1 or g[y-1][x]in[0,1,5,6]else{2,5,6}
o&={0,2,4,5}if x<1 or g[y][x-1]in[0,2,3,6]else{1,3,6}
if y>Y-2:o&={0,1,5,6}
if x>X-2:o&={0,2,3,6}
if y>0 and g[y-1][x]in[2,3,4]:
if'b'==I[y][x]and g[y-1][x]!=2:return 0
if'b'==I[y-1][x]:o&={2}
elif'w'==I[y-1][x]and g[y-2][x]==2:o&={5,6}
if x>0 and g[y][x-1]in[1,4,5]:
if'b'==I[y][x]and g[y][x-1]!=1:return 0
if'b'==I[y][x-1]:o&={1}
elif'w'==I[y][x-1]and g[y][x-2]==1:o&={3,6}
h=[r[:]for r in c]
if y>0 and g[y-1][x]in[2,3,4]:
if x>0 and g[y][x-1]in[1,4,5]:
if c[y-1][x]==c[y][x-1]:
if(6 not in o)+any(any(i!=c[y-1][x]and i!=-1 for i in r)for r in c)+any(I[v][u]!='.'and(v>y)+(u>x)for v in R(y,Y)for u in R(X)):return 0
g[y][x]=6
for v in R(y,Y):
for u in R(X):
if v!=y or u>x:g[v][u]=0
for y in R(Y):
for x in R(X):
if g[y][x]>0:break
f=[];d=-1;u,v=p,q=x,y
while(u,v)!=(p,q)or-1==d:f+=[u,v];d=([0,{0,2},{1,3},{2,3},{0,3},{0,1},{1,2}][g[v][u]]-{(d+2)%4}).pop();i,j={0:(u+1,v),1:(u,v-1),2:(u-1,v),3:(u,v+1)}[d];u,v=i,j
return f
else:
for v in R(y+1):
for u in R(X):
if h[v][u]==c[y][x-1]:h[v][u]=c[y-1][x]
h[y][x]=c[y-1][x]
else:h[y][x]=c[y-1][x]
elif x>0 and g[y][x-1]in[1,4,5]:h[y][x]=c[y][x-1]
else:h[y][x]=max(max(r)for r in c)+1
for n in sorted(list(o))[::-1]:
if n==0:h[y][x]=-1
if x>X-2:i,j=0,y+1
else:i,j=x+1,y
g[y][x]=n;r=S(g,h,i,j)
if r!=0:return r
return 0
for i in S():print i,
Ungolfed:
class Grid:
def __init__(self,input):
self.input = input.split('\n')
self.x = len(self.input[0])
self.y = len(self.input)
self.options = {'.':{0,1,2,3,4,5,6},'w':{1,2},'b':{3,4,5,6}}
def convert(self,grid):
directions = [None,{0,2},{1,3},{2,3},{0,3},{0,1},{1,2}]
for y in range(self.y):
for x in range(self.x):
if grid[y][x] != 0:
break
chain = []
start_pos = (x,y)
dir = -1
pos = start_pos
while dir == -1 or pos != start_pos:
chain.extend(pos)
x,y = pos
next_dir = (directions[grid[y][x]]-{(dir+2)%4}).pop()
if next_dir == 0: nx,ny = x+1,y
elif next_dir == 1: nx,ny = x,y-1
elif next_dir == 2: nx,ny = x-1,y
elif next_dir == 3: nx,ny = x,y+1
dir = next_dir
pos = (nx,ny)
return chain
def solve(self,grid=None,chain_ids=None,pos=(0,0)):
x,y = pos
if y >= self.y:
return None
if grid is None:
grid = [[-1]*self.x for i in range(self.y)]
if chain_ids is None:
chain_ids = [[-1]*self.x for i in range(self.y)]
options = self.options[self.input[y][x]].copy()
if y == 0 or grid[y-1][x] in [0,1,5,6]:
options &= {0,1,3,4}
else:
options &= {2,5,6}
if y == self.y-1:
options &= {0,1,5,6}
if x == 0 or grid[y][x-1] in [0,2,3,6]:
options &= {0,2,4,5}
else:
options &= {1,3,6}
if x == self.x-1:
options &= {0,2,3,6}
if y != 0 and grid[y-1][x] in [2,3,4]:
if self.input[y][x] == 'b' and grid[y-1][x] != 2:
return None
if self.input[y-1][x] == 'b':
options &= {2}
elif self.input[y-1][x] == 'w':
if grid[y-2][x] == 2:
options &= {5,6}
if x != 0 and grid[y][x-1] in [1,4,5]:
if self.input[y][x] == 'b' and grid[y][x-1] != 1:
return None
if self.input[y][x-1] == 'b':
options &= {1}
elif self.input[y][x-1] == 'w':
if grid[y][x-2] == 1:
options &= {3,6}
new_chain_ids = [[i for i in row] for row in chain_ids]
if y != 0 and grid[y-1][x] in [2,3,4]:
if x != 0 and grid[y][x-1] in [1,4,5]:
if chain_ids[y-1][x] == chain_ids[y][x-1]:
if 6 not in options:
return None
if any(any(i != chain_ids[y-1][x] and i != -1 for i in row) for row in chain_ids) or \
any(self.input[v][u] != '.' and (v!=y or u>x) for v in range(y,self.y) for u in range(self.x)):
return None
grid[y][x] = 6
for v in range(y,self.y):
for u in range(self.x):
if v != y or u > x:
grid[v][u] = 0
return self.convert(grid)
else:
for v in range(y+1):
for u in range(self.x):
if new_chain_ids[v][u] == chain_ids[y][x-1]:
new_chain_ids[v][u] = chain_ids[y-1][x]
new_chain_ids[y][x] = chain_ids[y-1][x]
else:
new_chain_ids[y][x] = chain_ids[y-1][x]
elif x != 0 and grid[y][x-1] in [1,4,5]:
new_chain_ids[y][x] = chain_ids[y][x-1]
else:
new_chain_ids[y][x] = max(max(row) for row in chain_ids)+1
for n in sorted(list(options),key=lambda n: -n):
grid[y][x] = n
if n == 0:
new_chain_ids[y][x] = -1
if x == self.x-1:
nx,ny = 0,y+1
else:
nx,ny = x+1,y
result = self.solve(grid,new_chain_ids,(nx,ny))
if result is not None:
return result
input = """
.....w.b.w..
ww..b...b...
.w.....b....
...wbww..b.b
....b.......
w.w.........
..w......b.b
.....bb.....
.....b.....w
w.ww..b.....
...w......w.
b..w.....b..
""".strip()
def print_grid(grid):
for y,row in enumerate(grid):
s = ""
for i in row:
s += {-1:'xxx',0:' ',1:' ',2:' | ',3:' ',4:' ',5:' | ',6:' | '}[i]
s += '\n'
for x,i in enumerate(row):
s += {-1:'x%sx',0:' %s ',1:'-%s-',2:' %s ',3:'-%s ',4:' %s-',5:' %s-',6:'-%s '}[i] % input.split('\n')[y][x]
s += '\n'
for i in row:
s += {-1:'xxx',0:' ',1:' ',2:' | ',3:' | ',4:' | ',5:' ',6:' '}[i]
s += '\n'
print s
result = Grid(input).solve()
print result