Berapa banyak bergerak?


16

Dengan dua posisi berbeda pada papan catur dan jenis keping, outputkan jumlah gerakan minimum yang diperlukan untuk keping itu untuk berpindah dari satu posisi ke posisi lain.

Aturan

Bagian yang diberikan bisa berupa Raja, Ratu, Benteng, Ksatria dan Uskup. (Input ini dapat diambil sebagai 5 karakter unik)

2 posisi dapat diambil dalam format apa pun yang nyaman,

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

Jika potongan tidak dapat mencapai di sana, output apa pun selain bilangan bulat positif.

Contohnya

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
Mengapa King membutuhkan 12 hingga a1-h6? Tidak bisakah King diag?
l4m2

@ l4m2, dikoreksi
Vedant Kandoi

1
@ ngn, Anda dapat menggunakan 0 untuk menunjukkan tidak dapat dijangkau, 2 posisi akan selalu berbeda.
Vedant Kandoi


1
Beberapa definisi (seperti ISO-80000-2) bilangan asli termasuk 0. Merekomendasikan untuk diganti dengan "bilangan bulat positif".

Jawaban:


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)

Cobalah online!

Begitu lama untuk kasus tepi, terima kasih Arnauld untuk memeriksa. Tes ksatria


@Arnauld Nah sudut benar-benar biaya
l4m2

Saya pikir Anda mungkin dapat menyimpan byte dengan mengganti yang terakhir maxdengan ternary.
Shaggy

170 byte (saya pikir. Saya menggunakan ponsel saya.)
Shaggy

@ Shaggy adalah apa yang Arnauld tunjukkan salah
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=.|⊢')⊣|-⌿⍵}

Cobalah online!

arg kiri adalah tipe piece: 0 = raja, 1 = ratu, 2 = benteng, 3 = ksatria, 4 = uskup; arg kanan adalah matriks 2x2 dari coords, setiap baris mewakili suatu posisi; mengembalikan 0 untuk tidak terjangkau

|-⌿⍵ menghitung pasangan [abs (∆x), abs (∆y)]

(⍎⍺⊃... )⊣memilih ekspresi dari daftar "..."; jika suatu fungsi, itu diterapkan ke |-⌿⍵; jika itu sebuah nilai (ini hanya terjadi untuk seorang ksatria), pastikan untuk mengembalikannya|-⌿⍵

  • raja: maks ( ⌈/) dari abs ∆-s

  • ratu: hapus angka nol (~∘0 ) dan hitung ( ) unik ( )

  • benteng: jumlah (+/ ) dari signa (monadik ×; 0 untuk 0, 1 untuk positif)

  • ksatria: {⍺∊⍵:0⋄1+⍺∇i/⍨∨⌿2=|×/↑⍵∘.-i←,⍳8 8}/,¨⊂¨↓⍵ - mulai dengan posisi awal dan hitung generasi knight bergerak secara rekursif sampai posisi akhir ada di set; kembalikan kedalaman rekursi

  • uskup: apakah paritas kedua ∆-s sama? ( 2=.|⊢, setara dengan =/2|⊢), gandakan hasil boolean (0 atau 1) dengan count-unique ( ≢∘∪)


Saya suka itu ⍎⍺⊃. Sangat pintar.
J. Sallé

@ J.Sallé terima kasih
ngn

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

Cobalah online!

Penjelasan

  • Papan adalah papan berbasis 0.
  • Nilai yang dikembalikan adalah bilangan bulat, direpresentasikan sebagai ganda. Tidak akan pernah ada bagian desimal.

Kode:

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

Kredit

  • -2 byte terima kasih kepada Arnauld , dan juga untuk membuat saya sadar bahwa saya memiliki masalah dengan semua kasus sudut saya.

1

Arang , 108 byte

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Penjelasan:

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

Daftarkan semua 64 kotak papan ke dalam variabel daftar kosong yang telah ditentukan.

≔⟦⟦η⟧⟧δ

Buat daftar daftar yang entri pertamanya adalah daftar yang berisi posisi awal.

W¬№§δ±¹ζ

Ulangi sampai entri terakhir dari daftar berisi posisi akhir.

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

Saring semua posisi papan yang merupakan langkah ksatria menjauh dari entri mana pun di entri terakhir daftar daftar dan dorong daftar itu ke daftar daftar. Ini termasuk posisi yang sebelumnya dikunjungi tetapi kami tidak tertarik pada mereka, jadi kami berakhir dengan pencarian papan pertama untuk posisi akhir.

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

Hitung perbedaan koordinat absolut antara posisi awal dan akhir.

≡θ

Pilih berdasarkan pada bagian input.

KI⌈ε

Jika itu raja maka cetak perbedaan koordinat absolut maksimum.

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

Jika itu ratu, cetak 2 kecuali dua perbedaannya sama atau satu nol.

RI∨¬⌊ε²

Jika rook maka cetak 2 kecuali salah satu perbedaannya adalah nol.

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

Jika itu adalah seorang uskup maka cetaklah 0 jika kuadratnya berseberangan, jika tidak cetaklah 2 kecuali kedua perbedaannya sama.

NI⊖Lδ

Jika itu seorang ksatria maka cetak jumlah loop yang diambil untuk menemukan posisi ujung.


1

Japt , 67 byte

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

Cobalah online!

Itu pengalaman yang cukup. Saya mengambil banyak inspirasi dari Jawaban APL yang sangat baik . Saya menduga ada banyak golf masih mungkin terutama dalam kode Knight.

Posisi adalah input pertama, dalam formulir [[x1,x2],[y1,y2]]. Seharusnya berfungsi dengan baik [[y1,y2],[x1,x2]]juga. Pilihan piece adalah input kedua, dengan 0 = raja, 1 = ratu, 2 = ksatria, 3 = benteng, 4 = uskup. Perhatikan bahwa Knight dan Rook ditukar dibandingkan dengan jawaban APL.

Penjelasan:

®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 Saran yang bagus. Ketika saya memasukkannya ke dalam, saya menemukan bahwa itu ábekerja lebih singkat [[1,2][2,1]].
Kamil Drakari

Wow, tidak pernah terpikir untuk menggunakannya á, bagus!
Produksi ETH

Beberapa saran lagi: Utersirat setelahnya @, sehingga Anda dapat menyimpan dua byte di fungsi knight. Anda juga dapat memulainya dengan @=ã ü;menyimpan yang lain. ( ãTriknya juga pintar :-))
ETHproduksi

@ ETHproductions Good find, saat-saat ketika U tersirat adalah salah satu hal yang belum sepenuhnya saya pahami.
Kamil Drakari
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.