Ile ruchów?

16

Biorąc pod uwagę dwie różne pozycje na szachownicy i rodzaj pionka, wypisz minimalną liczbę ruchów, które zajmie ten kawałek, aby przejść z jednej pozycji do drugiej.

Zasady

Dany element może być królem, królową, wieżą, rycerzem i biskupem. (To wejście może być traktowane jako dowolne 5 unikalnych znaków)

Dwie pozycje można przyjąć w dowolnym dogodnym formacie,

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

W przypadku gdy element nie może się tam dostać, wypisz coś innego niż dodatnią liczbę całkowitą.

Przykłady

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
Wedant Kandoi
źródło
1
Dlaczego król potrzebuje 12 do a1-h6? Czy King nie może odejść?
l4m2
@ l4m2, poprawione
Vedant Kandoi
1
@ngn, możesz użyć 0, aby wskazać nieosiągalność, 2 pozycje zawsze będą różne.
Vedant Kandoi
1
Niektóre definicje liczb naturalnych (np. ISO-80000-2) obejmują 0. Zaleca się zastępowanie przez „dodatnią liczbę całkowitą”.

Odpowiedzi:

9

JavaScript (Node.js) , 183 180 179 bajtów

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)

Wypróbuj online!

Tak długo na przypadku krawędzi, dziękuję Arnauld za sprawdzenie. Test rycerza

l4m2
źródło
@ Narożnik Arnauld Well naprawdę kosztuje
l4m2
Myślę, że możesz uratować bajt, zastępując ostatni maxprzez trójskładnik.
Kudłaty
170 bajtów (chyba. Jestem na telefonie)
Kudłaty
@ Shaggy był tym, co Arnauld zauważył, że źle
14m2
6

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

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

Wypróbuj online!

lewy arg jest typem sztuki: 0 = król, 1 = królowa, 2 = wieża, 3 = rycerz, 4 = biskup; prawy arg jest macierzą 2x2 współrzędnych, każdy rząd reprezentuje pozycję; zwraca 0 dla nieosiągalnego

|-⌿⍵ oblicza parę [abs (∆x), abs (∆y)]

(⍎⍺⊃... )⊣wybiera wyrażenie z listy „...”; jeśli jest to funkcja, jest stosowana do |-⌿⍵; jeśli jest to wartość (dzieje się tak tylko w przypadku rycerza), pamiętaj, aby ją zwrócić zamiast|-⌿⍵

  • king: max ( ⌈/) abs ∆-s

  • queen: usuwa zera ( ~∘0) i count ( ) unikalne ( )

  • gawron: sum ( +/) signa (monadic× ; 0 dla 0, 1 dla dodatniego)

  • rycerz: {⍺∊⍵:0⋄1+⍺∇i/⍨∨⌿2=|×/↑⍵∘.-i←,⍳8 8}/,¨⊂¨↓⍵ - zacznij od pozycji początkowej i rekurencyjnie oblicz generacje ruchów rycerza, aż pozycja końcowa znajdzie się w zestawie; zwraca głębokość rekurencji

  • biskup: czy parytety dwóch ∆ są równe? ( 2=.|⊢równoważne =/2|⊢) pomnożyć wynik boolowski (0 lub 1) przez liczbę unikatową ( ≢∘∪)

ngn
źródło
Kocham ⍎⍺⊃. Bardzo mądry.
J. Sallé
@ J.Sallé dzięki
ngn
2

Java (JDK) , 229 bajtów

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

Wypróbuj online!

Objaśnienia

  • Tablica jest tablicą 0.
  • Zwrócona wartość jest liczbą całkowitą reprezentowaną jako podwójna. Nigdy nie będzie żadnej części dziesiętnej.

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

Kredyty

  • -2 bajty dzięki Arnauldowi , a także za uświadomienie mi, że miałem problem ze wszystkimi moimi przypadkami.
Olivier Grégoire
źródło
1

Węgiel drzewny , 108 bajtów

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

Wypróbuj online! Link jest do pełnej wersji kodu. Wyjaśnienie:

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

Wyświetl wszystkie 64 kwadraty planszy w predefiniowanej zmiennej pustej listy.

≔⟦⟦η⟧⟧δ

Zrób listę, której pierwszym wpisem jest lista zawierająca pozycję początkową.

W¬№§δ±¹ζ

Powtarzaj, aż ostatni wpis na liście zawiera pozycję końcową.

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

Filtruj wszystkie pozycje planszy będące odejściem rycerza od dowolnego wpisu w ostatnim wpisie listy list i pchnij tę listę do listy list. Obejmuje to pozycje wcześniej odwiedzone, ale i tak nie byliśmy nimi zainteresowani, więc kończymy na pierwszym przeszukiwaniu tablicy pozycji końcowej.

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

Oblicz bezwzględne różnice współrzędnych między pozycją początkową i końcową.

≡θ

Wybierz na podstawie elementu wejściowego.

KI⌈ε

Jeśli jest królem, wydrukuj maksymalną bezwzględną różnicę współrzędnych.

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

Jeśli jest to królowa, wydrukuj 2, chyba że dwie różnice są równe lub jedna wynosi zero.

RI∨¬⌊ε²

Jeśli jest to wieża, wydrukuj 2, chyba że jedna z różnic wynosi zero.

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

Jeśli jest biskupem, wypisz 0, jeśli kwadraty mają przeciwną parzystość, w przeciwnym razie wypisz 2, chyba że dwie różnice są równe.

NI⊖Lδ

Jeśli jest to rycerz, wydrukuj liczbę pętli wykonanych w celu znalezienia pozycji końcowej.

Neil
źródło
1

Japt , 67 bajtów

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

Wypróbuj online!

To było całkiem przeżycie. Wiele inspiracji czerpałem z doskonałej odpowiedzi APL . Podejrzewam, że nadal istnieje wiele możliwości gry w golfa, szczególnie w kodzie Knight.

Pozycje są pierwszym wejściem, w formie [[x1,x2],[y1,y2]]. Powinno działać dobrze[[y1,y2],[x1,x2]] . Wybór elementu jest drugim wejściem, z 0 = król, 1 = królowa, 2 = rycerz, 3 = wieża, 4 = biskup. Zauważ, że Knight i Rook są zamienione w porównaniu do odpowiedzi APL.

Wyjaśnienie:

®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
Kamil Drakari
źródło
@ETHproductions Dobre sugestie. Podczas ich wkładania dowiedziałem się, że áudało mi się [[1,2][2,1]]znacznie skrócić .
Kamil Drakari
Wow, nigdy nie pomyślałbym, aby użyć á, miły!
ETHprodukcje
Kilka dodatkowych sugestii: Ujest niejawna po @, więc możesz zapisać dwa bajty w funkcji rycerza. Możesz też zacząć @=ã ü;od zapisania kolejnego. ( ãSztuczka też jest sprytna :-))
ETHprodukcje
@ETHproductions Dobre odkrycie, czasy, w których sugeruje się U, są jedną z rzeczy, których jeszcze w pełni nie zrozumiałem.
Kamil Drakari