受来自Esolangs.org非官方不和谐服务器。的讨论的启发
国际象棋周期是棋盘的一种安排,棋盘上每一棋子必须攻击另一棋子,而每一棋子必须攻击一次。
有效的想法是“连接”彼此,形成一个单一的循环链。下面是一个董事会的例子:

。
提交的棋盘必须采用任何有效的格式(字符串、字符串列表、2D数组、棋子位置列表、FEN、.)并输出一个真实或虚假的价值,无论董事会是否代表一个有效的周期。
若要创建自己的测试用例,请创建板这里,复制FEN框内容,并将其用作输入这里。。
芬:8/2B5/8/1N6/5N2/3B4/8/8,舔
董事会:
........
..B.....
........
.N......
.....N..
...B....
........
........输出:True (在插图中)
芬:8/8/8/3R4/8/8/8/8,舔
董事会:
........
........
........
...R....
........
........
........
........输出:False (Rook无法攻击self)
芬:1R4B1/3N4/3N4/3N1B2/8/2B2N2/4R1BB/R1N5,舔
董事会:
.R....B.
...N....
...N....
...N.B..
........
..B..N..
....R.BB
R.N.....输出:True
芬:6B1/4N2N/5B2/8/8/6B1/4N2N/5B2,舔
董事会:
......B.
....N..N
.....B..
........
........
......B.
....N..N
.....B..输出:False (多个周期)
芬:8/6R1/8/5R1N/3N4/8/5BB1/7N,舔
董事会:
........
......R.
........
.....R.N
...N....
........
.....BB.
.......N输出:False (Rook on f5攻击两件)
芬:8/8/8/8/8/8/8/8,舔(Tsh)
董事会:
........
........
........
........
........
........
........
........输出:False (循环中没有片段)
芬:8/8/8/2R2R2/8/8/8/8,舔(Tsh)
董事会:
........
........
........
..R..R..
........
........
........
........输出:True (两个连接的车钩,单周期)
芬:8/8/8/1R3B2/8/3R2N1/8/8,舔(罗宾·莱德)
董事会:
........
........
........
.R...B..
........
...R..N.
........
........输出:False
发布于 2021-05-03 08:50:50
o=DirectedEdges->True
i|->RelationGraph[(d=Abs[#1[[2]]-#2[[2]]];#1!=#2&&NoneTrue[i,RegionMember[Line[p={#1[[2]],#2[[2]]}]~RegionDifference~Point@p]@*Last]&&Switch[#1[[1]],r,Times@@d==0,b,Equal@@d,n,Sort@d=={1,2}])&,i,o]~IsomorphicGraphQ~CycleGraph[Length@i,o](使用[函数](http://reference.wolfram.com/language/ref/character/Function.html)而不是|->,因为TIO没有最新的语言版本)
定义一个函数,该函数将块位置列表作为输入,每个函数的形式为{piece, {row, column}},其中的片段是r、b或n中的一个。
未获金牌的解释:
i|->
IsomorphicGraphQ[ (*check if the following graphs are equivalent*)
CycleGraph[Length[i], DirectedEdges -> True],
(*cyclic graph with length of input*)
RelationGraph[ (*graph defined by a functional relation*)
(d = Abs[#1[[2]] - #2[[2]]]; (*set `d` to absolute difference in coordinates*)
#1 != #2 && (*no pieces attack themselves*)
NoneTrue[i, (*no other pieces are...*)
RegionMember[RegionDifference[Line[p = {#1[[2]], #2[[2]]}], Point[p]]] @* Last
] && (*between these two pieces*)
Switch[First @ #1, (*switch by attacking piece*)
r, Times @@ d == 0, (*rooks attack when one coordinate offset is zero*)
b, Equal @@ d, (*bishops attack when both offsets are equal*)
n, Sort[d] == {1, 2}] (*knights attack when one offset is 1 and the other is 2*)
)&, i, DirectedEdges->True], (*apply to list of pieces*)
]&发布于 2021-05-03 16:19:19
期望一个三胞胎(x,y,p)列表,其中(x,y)是作品的坐标,p是它的类型(0、1或2分别代表主教、骑士或鲁克)。
返回0或1。
a=>(g=(i,n,k)=>i>=0?m^(m|=1<<i)?a.map(([X,Y],j)=>(h=([x,y,t]=a[i],X-=x)*X)|(v=(Y-=y)*Y)&&![h-v,h+v-5,h*v][t]&a.every(([p,q])=>(S=Math.sign)(p-=x)-S(X)|S(q-=y)-S(Y)|(p*=p)+(q*=q)<1|[p-q,1][t]|p>=h&q>=v)?k=1/k?-1:j:0)|g(k,-~n):!i&!a[n]:0)(m=0)我们递归地遍历N条目的输入列表,从一个片段A转到一个受到A攻击的块B。我们测试是否最终返回到N迭代中的起始部分。
此外,如果以下情况,我们强迫搜索停止,而测试失败:
给出了A和B在(x_A,y_A)和(x_B,y_B)位置的两段,计算了dx=x_A-x_B和dy=y_A-y_B。
如下图所示,如果以下情况,则A攻击B:

对于罗克斯和主教,我们还必须确保在同一条射线之间没有碎片。这是这种面向片的方法的弱点,因为对应的代码( a.every())相当长。
a => ( // a[] = list of pieces
g = (i, n, k) => // g is a recursive function taking an index i and
// a number of moves n
i >= 0 ? // if i is a non-negative number:
m ^ (m |= 1 << i) ? // set the i-th bit in m; if it was not already set:
a.map(([X, Y], j) => // for each piece (X, Y) at position j in a[]:
( h = ( // load the position (x, y) and the type t
[x, y, t] = a[i], // of the i-th piece
X -= x // set: X = X - x, h = X²
) * X // Y = Y - y, v = Y²
) | (v = (Y -= y) * Y) // abort if both h and v are equal to 0
&& ![ h - v, // bishop: we must have h = v
h + v - 5, // knight: we must have h + v = 5
h * v // rook : we must have either h = 0 or v = 0
][t] & //
a.every(([p, q]) => // make sure that there is no closer piece (p, q)
(S = Math.sign) // that blocks the capture, which is not the case:
(p -= x) - S(X) // if it's not in the same direction
| S(q -= y) - S(Y) //
| (p *= p) + // or it's the capturing piece itself
(q *= q) < 1 //
| [p - q, 1][t] // or the capture types do not match
| p >= h & q >= v // or it's not blocking because it's further
) ? // end of every(); if all tests pass:
k = 1 / k ? -1 : j // update k to j, or -1 if it's already set
: // else:
0 // do nothing
) | // end of map()
g(k, -~n) // do a recursive call with i = k and n + 1
: // else:
!i & !a[n] // this is a full cycle if i = 0 and n = a.length
: // else:
0 // abort
)(m = 0) // initial call to g with i = m = 0https://codegolf.stackexchange.com/questions/224953
复制相似问题