Có bao nhiêu di chuyển?


16

Đưa ra hai vị trí khác nhau trên bàn cờ và loại quân cờ, xuất ra số lần di chuyển tối thiểu mà quân cờ sẽ đi từ vị trí này sang vị trí khác.

Quy tắc

Mảnh nhất định có thể là King, Queen, Rook, Knight và Bishop. (Đầu vào này có thể được lấy dưới dạng 5 ký tự duy nhất)

Hai vị trí có thể được thực hiện trong bất kỳ định dạng thuận tiện,

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

Trong trường hợp mảnh không thể đến đó, hãy xuất bất cứ thứ gì ngoài số nguyên dương.

Ví dụ

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
Tại sao King cần 12 đến a1-h6? Vua không thể đi diag?
l4m2

@ l4m2, đã sửa
Vedant Kandoi

1
@ngn, bạn có thể sử dụng 0 để biểu thị khả năng không truy cập được, 2 vị trí sẽ luôn khác nhau.
Vedant Kandoi


1
Một số định nghĩa (như ISO-80000-2) của các số tự nhiên bao gồm 0. Đề nghị thay thế bằng "số nguyên dương".

Câu trả lời:


9

JavaScript (Node.js) , 183 180 179 byte

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)

Hãy thử trực tuyến!

Rất lâu cho trường hợp cạnh, cảm ơn Arnauld đã kiểm tra. Kiểm tra hiệp sĩ


@Arnauld Góc thực sự có giá
l4m2

Tôi nghĩ rằng bạn có thể có thể lưu một byte bằng cách thay thế cuối cùng maxbằng một ternary.
Xù xì

170 byte (tôi nghĩ. Tôi đang ở trên điện thoại của tôi.)
Shaggy

@Shaggy là những gì Arnauld đã chỉ ra rằng sai
l4m2

6

APL (Dyalog Classic) , 117 107 105 103 98 97 95 92 89 87 byte

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

Hãy thử trực tuyến!

trái arg là loại mảnh: 0 = king, 1 = queen, 2 = rook, 3 = hiệp sĩ, 4 = giám mục; phải arg là một ma trận 2x2 của các coords, mỗi hàng đại diện cho một vị trí; trả về 0 cho không thể truy cập

|-⌿⍵ tính cặp [abs (x), abs (y)]

(⍎⍺⊃... )⊣chọn một biểu thức từ danh sách "..."; nếu đó là một chức năng, nó được áp dụng cho |-⌿⍵; nếu đó là một giá trị (điều này chỉ xảy ra với một hiệp sĩ), hãy đảm bảo trả lại nó thay vì|-⌿⍵

  • vua: max ( ⌈/) của abs-s

  • nữ hoàng: xóa số 0 ( ~∘0) và tính ( ) unique ( )

  • rook: sum ( +/) của Signa (monadic ×; 0 cho 0, 1 cho dương)

  • hiệp sĩ: {⍺∊⍵:0⋄1+⍺∇i/⍨∨⌿2=|×/↑⍵∘.-i←,⍳8 8}/,¨⊂¨↓⍵- bắt đầu với vị trí ban đầu và tính toán đệ quy các thế hệ hiệp sĩ cho đến khi vị trí cuối cùng được thiết lập; trở lại độ sâu đệ quy

  • giám mục: các chẵn lẻ của hai-s có bằng nhau không? ( 2=.|⊢, tương đương =/2|⊢) nhân kết quả boolean (0 hoặc 1) với số đếm duy nhất ( ≢∘∪)


Tôi yêu ⍎⍺⊃. Rất thông minh.
J. Sallé

@ J.Sallé cảm ơn
ngn 27/11/18

2

Java (JDK) , 229 byte

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

Hãy thử trực tuyến!

Giải thích

  • Bảng là một bảng dựa trên 0.
  • Giá trị trả về là một số nguyên, được biểu diễn dưới dạng kép. Sẽ không bao giờ có bất kỳ phần thập phân.

Mã số:

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

Tín dụng

  • -2 byte nhờ Arnauld , cũng như khiến tôi nhận ra rằng tôi có vấn đề với tất cả các trường hợp góc của mình.

1

Than , 108 byte

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

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã. Giải trình:

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

Liệt kê tất cả 64 ô vuông của bảng vào biến danh sách trống được xác định trước.

≔⟦⟦η⟧⟧δ

Lập danh sách các danh sách có mục nhập đầu tiên là danh sách chứa vị trí bắt đầu.

W¬№§δ±¹ζ

Lặp lại cho đến khi mục cuối cùng của danh sách chứa vị trí kết thúc.

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

Lọc tất cả các vị trí bảng là một hiệp sĩ di chuyển ra khỏi bất kỳ mục nào trong mục cuối cùng của danh sách danh sách và đẩy danh sách đó vào danh sách danh sách. Điều này bao gồm các vị trí đã truy cập trước đây nhưng dù sao chúng tôi không quan tâm đến chúng, vì vậy chúng tôi kết thúc với một tìm kiếm đầu tiên của bảng cho vị trí cuối.

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

Tính toán sự khác biệt tọa độ tuyệt đối giữa vị trí bắt đầu và kết thúc.

≡θ

Chọn dựa trên phần đầu vào.

KI⌈ε

Nếu đó là một vị vua thì in chênh lệch tọa độ tuyệt đối lớn nhất.

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

Nếu đó là nữ hoàng thì in 2 trừ khi hai khác biệt bằng nhau hoặc một bằng không.

RI∨¬⌊ε²

Nếu đó là một rook thì in 2 trừ khi một trong những khác biệt là không.

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

Nếu đó là một giám mục thì in 0 nếu các hình vuông có tính chẵn lẻ ngược lại in 2 trừ khi hai điểm khác nhau bằng nhau.

NI⊖Lδ

Nếu đó là một hiệp sĩ thì hãy in số vòng lặp để tìm vị trí kết thúc.


1

Japt , 67 byte

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

Hãy thử trực tuyến!

Đó là một kinh nghiệm khá. Tôi lấy rất nhiều cảm hứng từ sự xuất sắc trả lời APL . Tôi nghi ngờ có rất nhiều golf vẫn có thể, đặc biệt là trong mã Hiệp sĩ.

Các vị trí là đầu vào đầu tiên, trong mẫu [[x1,x2],[y1,y2]]. Nó sẽ hoạt động tốt trên[[y1,y2],[x1,x2]] . Lựa chọn mảnh là đầu vào thứ hai, với 0 = vua, 1 = nữ hoàng, 2 = hiệp sĩ, 3 = rook, 4 = giám mục. Lưu ý rằng Knight và Rook được hoán đổi so với câu trả lời của APL.

Giải trình:

®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 Gợi ý tốt. Trong khi tôi đặt chúng vào, tôi phát hiện ra rằng nó áđã rút ngắn [[1,2][2,1]]đáng kể.
Kamil Drakari

Wow, không bao giờ có thể nghĩ để sử dụng á, một trong những tốt đẹp!
Sản xuất ETH

Một vài gợi ý nữa: Uđược ẩn sau @, vì vậy bạn có thể lưu hai byte trong hàm hiệp sĩ. Bạn cũng có thể bắt đầu với @=ã ü;để lưu cái khác. (Thủ ãthuật cũng rất thông minh :-))
ETHproductions 29/11/18

@ETHproductions Tìm kiếm tốt, những lúc U được ngụ ý là một trong những điều tôi chưa nắm bắt được đầy đủ.
Kamil Drakari
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.