多少步?


16

给定棋盘上的两个不同位置和棋子的类型,输出该棋子从一个位置移动到另一个位置所需的最小移动次数。

规则

给定的片段可以是King,Queen,Rook,Knight和Bishop。(此输入可以视为任意5个唯一字符)

这2个职位可以采用任何方便的格式,

Example:
a8 b8 c8 d8 ... h8
a7 b7 c7 d7 ... h7
...
...
a1 b1 c1 d1 ... h1

万一无法到达该部分,请输出除正整数以外的任何值。

例子

i/p ---- o/p
King
a1,a4    3
a1,h6    7
b3,h5    6

Queen
a1,a4    1
a1,h6    2
b3,f7    1

Rook
a1,a4    1
a1,h6    2
h2,c7    2

Knight
a1,a4    3
a1,h6    4
b2,d3    1
b2,c3    2
b3,c3    3
a1,b2    4

Bishop
a1,a4    -1
a1,h6    2
b2,d3    -1
e1,h4    1

1
为什么国王需要12到a1-h6?金不能去诊断吗?
l4m2

@ l4m2,已更正
Vedant Kandoi '18

1
@ngn,您可以使用0表示无法访问,这2个位置将始终不同。
Vedant Kandoi,


1
自然数的某些定义(例如ISO-80000-2)包括0。推荐用“正整数”代替。

Answers:


9

的JavaScript(Node.js的)183个 180 179字节

with(Math)(a,b,c,d,t,x=abs(a-c),y=abs(b-d),v=x<y?y:x,q=0|.9+max(/[18][18]/.test(a+b+9+c+d)-v?x/2:3,y/2,x*y?x*y-4?(x+y)/3:3:2))=>t?t==2&x+y?0:t&1>x*y|t/2&x==y?1:t<4?2:v:q+(q+x+y&1)

在线尝试!

这么长的边缘情况,感谢Arnauld的检查。骑士测试


@Arnauld Well角落真的花了
l4m2 '18

我认为您可以通过用max三元数代替最后一个来节省字节。
毛茸茸的

170字节(我认为。我在用手机。)
Shaggy

@Shaggy是Arnauld指出的错误之处
l4m2

6

APL(Dyalog Classic)117 107 105 103 98 97 95 92 89 87字节

{(⍎⍺⊃'⌈/' '≢∘∪~∘0' '+/×' '{⍺∊⍵:0⋄1+⍺∇i/⍨∨⌿2=|×/↑⍵∘.-i←,⍳8 8}/,¨⊂¨↓⍵' '≢∘∪×2=.|⊢')⊣|-⌿⍵}

在线尝试!

左arg为棋子类型:0 =国王,1 =皇后,2 =车队,3 =骑士,4 =主教;右边的arg是一个2x2的坐标矩阵,每行代表一个位置;返回0表示不可达

|-⌿⍵ 计算对[abs(∆x),abs(∆y)]

(⍎⍺⊃... )⊣从“ ...”列表中选择一个表达式;如果它是一个函数,它的应用|-⌿⍵; 如果它是一个值(这仅发生在一个骑士身上),请确保返回它而不是|-⌿⍵

  • 国王:最大(⌈/绝对值∆-s的)

  • 女王:删除零(~∘0)和计数()唯一(

  • rook:+/signa的总和(monadic ×; 0代表0,1代表正)

  • 骑士:{⍺∊⍵:0⋄1+⍺∇i/⍨∨⌿2=|×/↑⍵∘.-i←,⍳8 8}/,¨⊂¨↓⍵-从初始位置开始,递归计算骑士移动的代数,直到最终位置在集合中;返回递归深度

  • 主教:两个∆的奇偶性相等吗?(2=.|⊢,等于=/2|⊢)将布尔结果(0或1)乘以count-unique(≢∘∪


我爱⍎⍺⊃。非常聪明。
J.Sallé18年

@J.Sallé感谢
NGN

2

Java(JDK),229字节

(p,a,b,c,d)->{c^=a/4*7;a^=a/4*7;d^=b/4*7;b^=b/4*7;int x=c<a?a-c:c-a,y=d<b?b-d:d-b,z=(x^=y^(y=y<x?y:x))-y;return p<1?x:p<2?z*y<1?1:2:p<3?2-z%2:p<4?x+y<2?3:(a<c?a+b:c+d)+x<2|x==2&z<1?4:z+2*Math.ceil((y-z)/(y>z?3:4.)):z<1?1:~z*2&2;}

在线尝试!

说明

  • 该板是基于0的板。
  • 返回值是一个整数,表示为双精度型。永远不会有任何小数部分。

码:

(p,a,b,c,d)->{                          // double-returning lambda.
                                        // p is the piece-type (0: king, 1: queen, 2: rook, 3: knight, 4: bishop)
                                        // a is the origin-X
                                        // b is the origin-Y
                                        // c is the destination-X
                                        // d is the destination-Y
 c^=a/4*7;a^=a/4*7;                     // Mirror board if origin is in the top part of the board
 d^=b/4*7;b^=b/4*7;                     // Mirror board if origin is in the left part of the board
 int x=c<a?a-c:c-a,                     // x is the X-distance between a and c
     y=d<b?b-d:d-b,                     // y is the Y-distance between b and d
     z=(x^=y^(y=y<x?y:x))-y;            // z is the delta between x and y
                                        // also, swap x and y if necessary so that x is the greater value.
               //    At this point,
               //     x      cannot be 0 (because the two positions are different)
               //     z<1    means the origin and destination are on the same diagonal
               //     y<1    means the origin and destination are on the same horizontal/vertical line
 return
  p<1?x:                                //  For a king, just take the max distance.
  p<2?z*y<1?1:2:                        //  For a queen, just move once if in direct line, or twice.
  p<3?2-z%2:                            //  For a rook, just move once if on the same horizontal or vertical line, or twice
  p<4?                                  //  For a knight, 
   x+y<2?3:                             //   Hardcode 3 if moving to the next horizontal/vertical square
   (a<c?a+b:c+d)+x<2|x==2&z<1?4:        //   Hardcode 4 if moving 2 cases in diagonal or one case in diagonal in a corner.
   z+2*Math.ceil((y-z)/(y>z?3:4.)):     //   Compute the number of moves necessary for the usual cases
  z<1?1:                                //  For a bishop, hardcode 1 if they are on the same diagonal
   ~z*2&2;                              //   Return 2 if they have the same parity else 0.
}

学分

  • -2个字节感谢Arnauld,也使我意识到我所有的极端情况都有问题。

1

木炭,108字节

F…β⁸F⁸⊞υ⁺ι⊕κ≔⟦⟦η⟧⟧δW¬№§δ±¹ζ⊞δΦυΦ§δ±¹⁼⁵ΣEμX⁻℅ξ℅§κπ²≔Eη↔⁻℅ι℅§ζκε≡θKI⌈εQI∨∨¬⌊ε⁼⊟ε⊟ε²RI∨¬⌊ε²BI∧¬﹪Σε²∨⁼⊟ε⊟ε²NI⊖Lδ

在线尝试!链接是详细版本的代码。说明:

F…β⁸F⁸⊞υ⁺ι⊕κ

将板的所有64个正方形列出到预定义的空列表变量中。

≔⟦⟦η⟧⟧δ

制作一个列表列表,其第一个条目是包含开始位置的列表。

W¬№§δ±¹ζ

重复直到列表的最后一个条目包含结束位置。

⊞δΦυΦ§δ±¹⁼⁵ΣEμX⁻℅ξ℅§κπ²

过滤所有骑士离开列表列表最后一个条目中的所有木板位置,并将该列表推入列表列表。这包括以前访问过的职位,但是我们对它们都不感兴趣,因此我们首先在董事会中进行了一次广度的最终职位搜索。

≔Eη↔⁻℅ι℅§ζκε

计算起点和终点之间的绝对坐标差。

≡θ

根据输入片段进行选择。

KI⌈ε

如果是国王,则打印最大绝对坐标差。

QI∨∨¬⌊ε⁼⊟ε⊟ε²

如果是女王/王后,则打印2,除非两个差相等或一个为零。

RI∨¬⌊ε²

如果是菜鸟,请打印2,除非其中之一是零。

BI∧¬﹪Σε²∨⁼⊟ε⊟ε²

如果是主教,则如果正方形具有相反的奇偶性,则打印0;否则,除非两个差相等,否则打印2。

NI⊖Lδ

如果是骑士,则打印要查找终点位置的循环数。


1

Japt,67个字节

®ra
g[_rw}_â è}@=ã ü;@pUÌïVõ á ÈíaY})Ìde[TT]}a Ä}_è}_ra v *Zâ l}]gV

在线尝试!

那是相当的经验。我从出色的APL答案中学到了很多灵感。我怀疑还有很多打高尔夫球的可能,尤其是在骑士守则中。

位置是形式的第一个输入[[x1,x2],[y1,y2]]。它应该可以正常工作[[y1,y2],[x1,x2]]。棋子选择是第二个输入,0 =国王,1 =皇后,2 =骑士,3 =前锋,4 =主教。请注意,与APL答案相比,Knight和Rook被交换了。

说明:

®ra         :Turn absolute positions into relative movement and store in U
®           : For each of X and Y
 ra         : Get the absolute difference between the start position and the end position

g[...]gV    :Apply the appropriate function
 [...]      : A list of functions
      gV    : Get the one indicated by the second input
g           : Apply it to U

_rw}        :King function
 rw         : Get the maximum of X and Y

_â è}       :Queen function
 â          : Get unique elements
   è        : Count non-zero elements

@=ã ü;@pUÌï2õ á ÈíaY})Ìde[TT]}a Ä}  :Knight function
 =ã ü;                              : Wrap U twice (U -> [[U]])
      @                      }a Ä   : Repeat until True; return number of tries:
        UÌ                          :  Get the previous positions
          ï                         :  Cartesian product with:
           2õ                       :   The range [1,2]
              á                     :   All permutations, i.e. [[1,2],[2,1]]
                ÈíaY})              :  Apply each move to each position
       p                            :  Store the new positions
                      Ìde[TT]       :  True if any are at the destination

_è}         :Rook function
 è          : Count non-zero elements

_ra v *Zâ l}    :Bishop function
 ra             : Absolute difference between X and Y
    v           : Is divisible by 2? (returns 1 or 0)
      *         : Times:
       Zâ       :  Get the unique elements
          l     :  Count them

@ETHproductions好建议。当我将它们放入时,我发现该方法á可以[[1,2][2,1]]大大缩短时间。
卡米尔·达卡里

哇,从来没有想过要使用á,不错的一个!
ETHproductions

还有两个建议:U在后面是隐式的@,因此您可以在knight函数中保存两个字节。您也可以@=ã ü;以保存另一个开始。(ã技巧也很聪明:
ETHproductions

@ETHproductions很好的发现,隐含U的时间是我尚未完全掌握的事情之一。
卡米尔·德拉卡里
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.