在围棋板上移动


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.