Python - 1669
Yine de oldukça uzun, ancak son örneği bilgisayarımda bir saniyenin altında çalıştıracak kadar hızlı. Muhtemelen hız maliyetini kısaltmak mümkündür, ancak şimdilik bu çözümsüz koda eşdeğerdir.
Son test durumu için örnek çıktı:
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
Kod:
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