何回移動しますか?


16

チェス盤の2つの異なる位置と駒の種類を指定して、その駒が1つの位置から別の位置に移動するために必要な最小移動数を出力します。

ルール

指定された作品は、キング、クイーン、ルーク、ナイト、ビショップになります。(この入力は、任意の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
Kingが12からa1-h6を必要とするのはなぜですか?キングは診断できませんか?
l4m2

@ l4m2、修正済み
Vedant Kandoi

1
@ ngn、0を使用して到達不能を示すことができます。2つの位置は常に異なります。
ヴェダントカンドー


1
自然数の一部の定義(ISO-80000-2など)には0が含まれています。「正の整数」で置き換えることをお勧めします。

回答:


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

最後maxを3進数に置き換えることで、1バイトを節約できると思います。
シャギー

170バイト(私は思う。私は自分の電話にいる。)
シャギー

@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=.|⊢')⊣|-⌿⍵}

オンラインでお試しください!

左引数はピース型です:0 =王、1 =女王、2 =ルーク、3 =騎士、4 =司教; 右引数は座標の2x2行列で、各行は位置を表します。到達不能の場合は0を返します

|-⌿⍵ ペア[abs(∆x)、abs(∆y)]を計算します

(⍎⍺⊃... )⊣「...」リストから式を選択します。関数の場合は、に適用され|-⌿⍵ます; 値の場合(これはナイトの場合にのみ発生します)、代わりに|-⌿⍵

  • 王:⌈/腹筋∆-sの最大()

  • クイーン:ゼロ(~∘0)およびカウント()ユニーク()を削除します

  • ルーク:+/signaの合計()(単項×; 0の場合は0、正の場合は1)

  • ナイト:{⍺∊⍵:0⋄1+⍺∇i/⍨∨⌿2=|×/↑⍵∘.-i←,⍳8 8}/,¨⊂¨↓⍵-初期位置から開始し、最終位置がセットに含まれるまでナイトの動きの世代を再帰的に計算します。再帰の深さを返す

  • ビショップ:2つの∆-sのパリティは等しいですか?(2=.|⊢、と同等=/2|⊢)ブール結果(0または1)にcount-unique(≢∘∪)を掛けます


私は大好き⍎⍺⊃です。非常に賢い。
J.サレ

@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ベースのボードです。
  • 戻り値は整数であり、doubleとして表されます。小数部分はありません。

コード:

(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.
}

クレジット

  • Arnauldのおかげで-2バイト、すべてのコーナーケースで問題が発生したことを実感させてくれました。

1

、108バイト

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

オンラインでお試しください!リンクは、コードの詳細バージョンです。説明:

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

ボードの64マスすべてを、事前定義された空のリスト変数にリストします。

≔⟦⟦η⟧⟧δ

最初のエントリが開始位置を含むリストであるリストのリストを作成します。

W¬№§δ±¹ζ

リストの最後のエントリに終了位置が含まれるまで繰り返します。

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

リストのリストの最後のエントリの任意のエントリからのナイトの移動であるすべてのボード位置をフィルタリングし、そのリストをリストのリストにプッシュします。これには以前に訪問したポジションが含まれますが、とにかくそれらには興味がなかったので、最終ポジションのボードを幅広に最初に検索することになります。

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

開始位置と終了位置の間の絶対座標の差を計算します。

≡θ

入力ピースに基づいて選択します。

KI⌈ε

キングの場合、最大絶対座標差を出力します。

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

クイーンの場合、2つの差が等しいか、1つがゼロでない限り、2を出力します。

RI∨¬⌊ε²

それがルークの場合、違いの1つがゼロでない限り2を出力します。

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

それが司教である場合、正方形が反対のパリティである場合は0を出力し、そうでない場合は2つの差が等しくない限り2を出力します。

NI⊖Lδ

ナイトの場合、ループの数を出力して終了位置を見つけます。


1

Japt、67バイト

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

オンラインでお試しください!

それはかなりの経験でした。優れたAPL Answerから多くのインスピレーションを受けました。。特にナイトのコードでは、まだ多くのゴルフが可能だと思います。

位置は、フォームの最初の入力[[x1,x2],[y1,y2]]です。[[y1,y2],[x1,x2]]うまく動作するはずです。ピースの選択は2番目の入力で、0 =王、1 =女王、2 =騎士、3 =ルーク、4 =司教です。KnightとRookは、APLの回答と比較して交換されていることに注意してください。

説明:

®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@で暗黙的であるため、ナイト関数で2バイトを保存できます。@=ã ü;別のファイルを保存するために開始することもできます。(ãトリックも賢い:
ETHproductions

@ETHproductions良い発見、Uが暗示される時代は、私がまだ完全に把握していないことの1つです。
カミルドラカリ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.