Kaç hamle?


16

Bir satranç tahtasında iki farklı pozisyon ve parça türü göz önüne alındığında, o parçanın bir konumdan diğerine geçmesi için gereken minimum hamle sayısını verin.

kurallar

Verilen parça Kral, Kraliçe, Kale, Şövalye ve Piskopos olabilir. (Bu giriş 5 benzersiz karakter olarak alınabilir)

2 pozisyon herhangi bir uygun formatta alınabilir,

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

Parçanın oraya ulaşamaması durumunda, pozitif bir tamsayıdan başka bir şey çıkarmayın.

Örnekler

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 neden 12 ila a1-h6'ya ihtiyaç duyar? King tanı koyamıyor mu?
l4m2

@ l4m2, düzeltilmiş
Vedant Kandoi

1
@ngn, ulaşılamazlığı belirtmek için 0 kullanabilirsiniz, 2 konum her zaman farklı olacaktır.
Vedant Kandoi


1
Doğal sayıların bazı tanımları (ISO-80000-2 gibi) 0'ı içerir. "Pozitif tamsayı" ile değiştirilmesini tavsiye edin.

Yanıtlar:


9

JavaScript (node.js) , 183 , 180 179 bayt

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)

Çevrimiçi deneyin!

Kenar kasa için çok uzun, kontrol için Arnauld'a teşekkür ederim. Şövalye testi


@Arnauld Şey köşesi gerçekten maliyet
l4m2

Sanırım sonuncuyu maxbir üçlü ile değiştirerek bir bayt kaydedebilirsiniz .
Shaggy

170 bayt (Sanırım. Telefonumdayım.)
Shaggy

@Shaggy Arnauld bu yanlış işaret ne oldu
l4m2

6

APL (Dyalog Klasik) , 117 107 105 103 98 97 95 92 89 87 bayt

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

Çevrimiçi deneyin!

sol arg parça tipidir: 0 = kral, 1 = kraliçe, 2 = kale, 3 = şövalye, 4 = fil; sağ arg 2x2'lik bir koordinat matrisidir, her sıra bir konumu temsil eder; ulaşılamaz için 0 döndürür

|-⌿⍵ çifti hesaplar [abs (∆x), abs (∆y)]

(⍎⍺⊃... )⊣"..." listesinden bir ifade seçer; eğer bu bir işlev ise |-⌿⍵; bu bir değerse (bu sadece bir şövalye için olur), bunun yerine|-⌿⍵

  • kral: ⌈/abs ∆-s'nin max ( ) değeri

  • queen: zeroes ( ~∘0) öğesini kaldır ve count ( ) unique ( )

  • kale: +/signa'nın toplamı ( ) (monadik ×; 0 için 0, pozitif için 1)

  • şövalye: {⍺∊⍵:0⋄1+⍺∇i/⍨∨⌿2=|×/↑⍵∘.-i←,⍳8 8}/,¨⊂¨↓⍵- başlangıç ​​pozisyonu ile başlayın ve son pozisyon sette oluncaya kadar nesli şövalye hareketlerini tekrar tekrar hesaplayın; geri dönüş derinliği

  • Piskopos: İki s-nin paritesi eşit mi? ( 2=.|⊢, eşdeğer =/2|⊢) boole sonucunu (0 veya 1) count-unique ( ≢∘∪) ile çarpın


Seviyorum ⍎⍺⊃. Çok zeki.
J. Sallé

J.Sallé teşekkürler
ngn

2

Java (JDK) , 229 bayt

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

Çevrimiçi deneyin!

açıklamalar

  • Anakart 0 tabanlı bir anakarttır.
  • Döndürülen değer, bir çift olarak temsil edilen bir tamsayıdır. Asla ondalık kısım olmayacak.

Kod:

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

Kredi

  • Arnauld sayesinde -2 bayt ve tüm köşe davalarımda bir sorun yaşadığımı fark etmem için.

1

Kömür , 108 bayt

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

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı versiyonudur. Açıklama:

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

Kartın 64 karesinin tümünü önceden tanımlanmış boş liste değişkenine listeleyin.

≔⟦⟦η⟧⟧δ

İlk girişi başlangıç ​​konumunu içeren bir liste olan listelerin bir listesini yapın.

W¬№§δ±¹ζ

Listenin son girişi son konumu alana kadar tekrarlayın.

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

Bir şövalyenin tüm tahta pozisyonlarını liste listesinin son girişindeki herhangi bir girişten uzaklaştırarak filtreleyin ve bu listeyi liste listesine itin. Bu, daha önce ziyaret edilen pozisyonları içerir, ancak yine de bunlarla ilgilenmedik, bu yüzden son pozisyon için tahtada ilk genişlik aramasıyla sonuçlanıyoruz.

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

Başlangıç ​​ve bitiş konumları arasındaki mutlak koordinat farklılıklarını hesaplayın.

≡θ

Giriş parçasına göre seçin.

KI⌈ε

Eğer bir kralsa, maksimum mutlak koordinat farkını yazdırın.

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

Bir kraliçe ise, iki fark eşit değilse veya biri sıfır değilse 2 yazdırın.

RI∨¬⌊ε²

Bir kale ise, farklılıklardan biri sıfır olmadığı sürece 2 yazdırın.

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

Eğer bir piskopossa, kareler ters parite ise 0 yazdırın, aksi takdirde iki fark eşit değilse 2 yazdırın.

NI⊖Lδ

Bir şövalye ise, son konumu bulmak için alınan döngü sayısını yazdırın.


1

Japt , 67 bayt

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

Çevrimiçi deneyin!

Bu oldukça büyük bir deneyimdi. Mükemmel APL cevabından çok ilham aldım . Özellikle şövalye kodunda hala golf bir sürü mümkün olduğundan şüpheleniyorum.

Konumlar, formdaki ilk girdidir [[x1,x2],[y1,y2]]. Üzerinde [[y1,y2],[x1,x2]]de iyi çalışmalıdır. Parça seçimi ikinci girdi, 0 = kral, 1 = kraliçe, 2 = şövalye, 3 = kale, 4 = fil. Knight ve Rook'un APL cevabı ile karşılaştırıldığında değiştirildiğine dikkat edin.

Açıklama:

®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 İyi öneriler. Onları yerleştirirken, bunun önemli ölçüde ákısalmaya çalıştığını öğrendim [[1,2][2,1]].
Kamil Drakari

Vay canına, asla kullanmayı düşünmezdim á, güzel olan!
ETHproductions 29:18

Birkaç öneri daha: Uörtüktür @, böylece şövalye işlevinde iki bayt kaydedebilirsiniz. Ayrıca bir @=ã ü;başkasını kaydetmek için ile başlatabilirsiniz . ( ãHile çok zekidir :-))
ETHproductions

@ETHproductions İyi bul, U ima edildiği zamanlar henüz tam olarak kavramadığım şeylerden biri.
Kamil Drakari
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.