在围棋板上移动


13

您将获得棋牌游戏和棋局的位置。您需要输出此举是否合法,以及新董事会职位(如果合法)。

围棋动作的简要说明:游戏包括将黑白棋子(“石头”)交替放置在方形板上的空白处。相互连接(4路)的相同颜色的零件组称为组。板上邻近某个组(也是4向)的空白位置被视为该组的“自由”。拥有0个自由的组被捕获(从董事会中删除)。除非捕获一个或多个对手的组(此过程中获得了自由,因此实际上并未被捕获),否则将导致其自身的组被捕获(“自杀”)的举动是非法的。

对于那些相关人员,您不需要处理ko(和superko),即,您可以假定ko捕获是合法的。如果您不知道这是什么意思,请遵循上述规则,就可以了。

输入: 2到19(含)之间的数字n代表棋盘的大小,n行n介于0到2(含2)之间的n数代表棋盘的位置,后跟3个以空格分隔的数字,代表进行的动作。在棋盘位置,0表示空白,1表示黑色石头,2表示白色石头。此举使石头的列,行和颜色(1或2)得以放置。列和行从0开始,从0到n-1(含)范围内,并按与板输入相同的顺序计数。

您可以假定给定的董事会职位是合法的(所有团体至少有一个自由)。

输出:如果移动是否合法,则该行包含1或0(如果愿意,则为true / false),然后(仅在合法移动的情况下)以与输入相同的格式跟随新的木板位置。

得分:完整源代码的字节数,越小越好。如果使用非ascii字符,则要加收20%的罚款,如果无法使用免费软件在Linux中测试您的代码,则要加收20%的罚款。

规则:没有网络连接,也没有第三方库。您的程序应使用标准的输入和输出流,或您的编程语言使用的标准等效流。

例子:

1) Input:

2
10
01
1 0 2

Output:

0

2) Input:

2
10
11
1 0 2

Output:

1
02
00

3) Input:

5
22122
22021
11211
02120
00120
2 1 1

Output:

1
00100
00101
11011
02120
00120

4) Input:

6
000000
011221
121121
122221
011110
000000
4 0 1

Output:

1
000010
011221
121121
122221
011110
000000

Answers:


2

Python 3(557 504 488)

import sys
s=sys.stdin
M=int(next(s))+1
j=Z=M*M-M
S=s.read(Z)
P=0
b=[0]*3
while j>0:j-=1+(j%M<1);b[int(S[j])]|=1<<j;P|=1<<j
N=lambda x:(x<<1|x>>1|x<<M|x>>M)&P&~x
def h(a,b):t=a|N(a)&b;return h(t,b)if t!=a else a
c,r,m=map(int,next(s).split())
o=m%2+1
p=1<<M*r+c
b[m]|=p
for n in(p<<1,p>>1,p<<M,p>>M):
 e=h(n&P,b[o])
 if~b[m]&N(e)<1<=n&b[o]:b[o]&=~e
_,B,W=b
g=~b[o]&N(h(p,b[m]))>=1>~_&p
print(+g)
q=''
while j<Z:
 r=1<<j
 if g*j%M>M-2:print(q);q=''
 else:q+='012E'[(r&B>0)+(r&W>0)*2]
 j+=1

使用3个位域来表示电路板-黑色,白色和空白空间各一个。使寻找邻居N和获得连锁h经营变得非常简洁。

带有大量评论的非公开版本:https://gist.github.com/airfrog/8429006


每行末尾都有很多空格,发布时的文件有2732个字节。
— aidtsu退出是因为SE为EVIL,2014年

@aditsu现在应该解决
— airfrog

大小仍然是错误的,现在应该是555 :)另外,我想知道是否仍然可以通过使用更多的分号来节省一些字节。
— aidtsu退出是因为SE为EVIL,2014年

虫子?输入:6 000000 011221 121121 122221 011110 000000 4 0 1输出:0。现在又增加了如实例4
— aditsu退出,因为SE是邪恶的

该错误已修复,我也发现并修复了高尔夫中可能要添加的另一个错误示例。输入:5 22100 20211 12211 12120 01120 1 1 2输出应该是0
— airfrog

2

蟒蛇(912 1004)

def o():
 n=int(raw_input(''))
 i=[raw_input('') for r in range(n+1)]
 b=[map(int,list(r)) for r in i[:n]]
 u,v,w=map(int,i[n].split(' '))
 if b[v][u]!=0:return 0
 b[v][u]=w
 if w==1:q=2
 elif w==2:q=1
 else:return 0
 f=[[],[],[]]
 h=[[],[],[]]
 g=[range(z*n,(z+1)*n) for z in range(n)]
 d=[(1,0),(-1,0),(0,1),(0,-1)]
 m=lambda z:max(0,min(n-1,z))
 t=[0,1,2,0,1]
 for j,s in enumerate(t):
  for r in range(n):
   for c in range(n):
    for y,x in map(lambda p:(m(r+p[0]),m(c+p[1])),d):
     if s==0:
      if b[y][x]==b[r][c]:
       if g[y][x]!=min(g[y][x],g[r][c]):
        t.insert(j+1,0)
       g[y][x]=g[r][c]=min(g[y][x],g[r][c])
     elif s==1:
      if g[r][c] not in h[b[r][c]]:
       h[b[r][c]].append(g[r][c])
      if b[y][x]==0 and g[r][c] not in f[b[r][c]]:
       f[b[r][c]].append(g[r][c])
    if s==2:
     if b[r][c]==q and g[r][c] not in f[b[r][c]]:
      b[r][c]=0
 h[w].sort()
 f[w].sort()
 if h[w]!=f[w]:return 0
 return "1\n"+'\n'.join([''.join(map(str,r)) for r in b])
print o()

演练:解析输入,检查移动是否在空白处,进行移动,初始化“组”网格,通过检查相邻石头的颜色(s = 0)简化/最小化组网格,并重复进行直到完全最小化,再检查对于团体自由(s = 1),移除没有自由的团体(s = 2)的对手石块,重复s = 0和s = 1,检查所有玩家团体是否具有自由,并返回结果。

这可能可以大大缩短...

交互式示例运行:

2
10
01
1 0 2
0

2
10
11
1 0 2
1
02
00

5
22122
22021
11211
02120
00120
2 1 1
1
00100
00101
11011
02120
00120

6
000000
011221
121121
122221
011110
000000
4 0 1
1
000010
011221
121121
122221
011110
000000

1
您的程序不执行任何操作,仅定义一个函数。
— aidtsu退出是因为SE为EVIL,2014年

交互式运行它,并使用print o()调用它,如示例运行中所示...
— 2014年

不。它应该是您从命令行运行的独立程序。此外,这也将使其更短。
— aidtsu退出是因为SE为EVIL,2014年

通过在最后一行添加打印o()来修复此问题
— 2014年

为什么不只使用函数体(已突出)?我想你也不能新增例如4
— aditsu退出,因为SE是邪恶的
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.