首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >这是国际象棋周期吗?

这是国际象棋周期吗?
EN

Code Golf用户
提问于 2021-05-03 04:58:28
回答 2查看 2K关注 0票数 24

受来自Esolangs.org非官方不和谐服务器。的讨论的启发

指令

国际象棋周期是棋盘的一种安排,棋盘上每一棋子必须攻击另一棋子,而每一棋子必须攻击一次。

有效的想法是“连接”彼此,形成一个单一的循环链。下面是一个董事会的例子:

你只会得到骑士、鲁克斯和主教的棋盘。

提交的棋盘必须采用任何有效的格式(字符串、字符串列表、2D数组、棋子位置列表、FEN、.)并输出一个真实或虚假的价值,无论董事会是否代表一个有效的周期。

测试案例

若要创建自己的测试用例,请创建板这里,复制FEN框内容,并将其用作输入这里。

芬:8/2B5/8/1N6/5N2/3B4/8/8

董事会:

代码语言:javascript
复制
........
..B.....
........
.N......
.....N..
...B....
........
........

输出:True (在插图中)

芬:8/8/8/3R4/8/8/8/8

董事会:

代码语言:javascript
复制
........
........
........
...R....
........
........
........
........

输出:False (Rook无法攻击self)

芬:1R4B1/3N4/3N4/3N1B2/8/2B2N2/4R1BB/R1N5

董事会:

代码语言:javascript
复制
.R....B.
...N....
...N....
...N.B..
........
..B..N..
....R.BB
R.N.....

输出:True

芬:6B1/4N2N/5B2/8/8/6B1/4N2N/5B2

董事会:

代码语言:javascript
复制
......B.
....N..N
.....B..
........
........
......B.
....N..N
.....B..

输出:False (多个周期)

芬:8/6R1/8/5R1N/3N4/8/5BB1/7N

董事会:

代码语言:javascript
复制
........
......R.
........
.....R.N
...N....
........
.....BB.
.......N

输出:False (Rook on f5攻击两件)

芬:8/8/8/8/8/8/8/8舔(Tsh)

董事会:

代码语言:javascript
复制
........
........
........
........
........
........
........
........

输出:False (循环中没有片段)

芬:8/8/8/2R2R2/8/8/8/8舔(Tsh)

董事会:

代码语言:javascript
复制
........
........
........
..R..R..
........
........
........
........

输出:True (两个连接的车钩,单周期)

芬:8/8/8/1R3B2/8/3R2N1/8/8舔(罗宾·莱德)

董事会:

代码语言:javascript
复制
........
........
........
.R...B..
........
...R..N.
........
........

输出:False

其他信息

  • 只要它是一致的,你可以用任何数字或字符来表示碎片和空方块。
  • 给定的板将始终是8x8和有效的,即不包含任何无效字符。
EN

回答 2

Code Golf用户

发布于 2021-05-03 08:50:50

Wolfram语言,259个字节

代码语言:javascript
复制
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}},其中的片段是rbn中的一个。

未获金牌的解释:

代码语言:javascript
复制
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*)
]&
票数 9
EN

Code Golf用户

发布于 2021-05-03 16:19:19

JavaScript (ES6),241个字节

期望一个三胞胎(x,y,p)列表,其中(x,y)是作品的坐标,p是它的类型(012分别代表主教、骑士或鲁克)。

返回01

代码语言:javascript
复制
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迭代中的起始部分。

此外,如果以下情况,我们强迫搜索停止,而测试失败:

  • 我们到达一个已经被访问过的部分,而不是第一个(例如,两个rooks之间的相互攻击,这将导致一个无限循环)。
  • 我们检测到的攻击比任何一件都多

攻击

给出了AB(x_A,y_A)(x_B,y_B)位置的两段,计算了dx=x_A-x_Bdy=y_A-y_B

如下图所示,如果以下情况,则A攻击B

  • A是一辆车,我们有dx^2=0,\:dy^2>0dx^2>0,\:dy^2=0
  • A是主教和dx^2=dy^2
  • A是骑士和dx^2+dy^2=5

对于罗克斯和主教,我们还必须确保在同一条射线之间没有碎片。这是这种面向片的方法的弱点,因为对应的代码( a.every())相当长。

评论

代码语言:javascript
复制
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 = 0
票数 8
EN
页面原文内容由Code Golf提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codegolf.stackexchange.com/questions/224953

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档