পাইথন - 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