Combien de coups?

16

Étant donné deux positions différentes sur un échiquier et le type de pièce, sortez le nombre minimum de mouvements qu'il faudra pour que cette pièce passe d'une position à une autre.

Règles

La pièce donnée peut être King, Queen, Rook, Knight et Bishop. (Cette entrée peut être considérée comme 5 caractères uniques)

Les 2 positions peuvent être prises dans n'importe quel format pratique,

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

Dans le cas où la pièce ne peut pas l'atteindre, sortez autre chose qu'un entier positif.

Exemples

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
Vedant Kandoi
la source
1
Pourquoi King a-t-il besoin de 12 à A1-H6? King ne peut-il pas faire de diagnostic?
l4m2
@ l4m2, corrigé
Vedant Kandoi
1
@ngn, vous pouvez utiliser 0 pour indiquer l'inaccessibilité, les 2 positions seront toujours différentes.
Vedant Kandoi
1
Certaines définitions (telles que ISO-80000-2) des nombres naturels incluent 0. Recommander la substitution par "entier positif".

Réponses:

9

JavaScript (Node.js) , 183 180 179 octets

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)

Essayez-le en ligne!

Si longtemps pour le cas de bord, merci Arnauld pour avoir vérifié. Test de chevalier

l4m2
la source
@Arnauld Well corner a vraiment coûté
l4m2
Je pense que vous pourriez être en mesure d'économiser un octet en remplaçant le dernier maxpar un ternaire.
Shaggy
170 octets (je pense. Je suis sur mon téléphone.)
Shaggy
@Shaggy était ce qu'Arnauld a dit de mal
l4m2
6

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

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

Essayez-le en ligne!

l'argument de gauche est de type pièce: 0 = roi, 1 = reine, 2 = tour, 3 = chevalier, 4 = évêque; l'argument de droite est une matrice 2x2 de coordonnées, chaque ligne représentant une position; renvoie 0 pour inaccessible

|-⌿⍵ calcule la paire [abs (∆x), abs (∆y)]

(⍎⍺⊃... )⊣choisit une expression dans la liste "..."; si c'est une fonction, elle est appliquée à |-⌿⍵; si c'est une valeur (cela ne se produit que pour un chevalier), assurez-vous de la retourner au lieu de|-⌿⍵

  • roi: max ( ⌈/) des abs ∆-s

  • reine: supprimer les zéros ( ~∘0) et compter ( ) unique ( )

  • tour: somme ( +/) de signa (monadique ×; 0 pour 0, 1 pour positif)

  • chevalier: {⍺∊⍵:0⋄1+⍺∇i/⍨∨⌿2=|×/↑⍵∘.-i←,⍳8 8}/,¨⊂¨↓⍵- commencez par la position initiale et calculez récursivement des générations de mouvements de chevalier jusqu'à ce que la position finale soit dans l'ensemble; retourner la profondeur de récursivité

  • évêque: les parités des deux ∆-s sont-elles égales? ( 2=.|⊢, équivalent à =/2|⊢) multipliez le résultat booléen (0 ou 1) par count-unique ( ≢∘∪)

ngn
la source
J'adore le ⍎⍺⊃. Très intelligent.
J.Sallé
@ J.Sallé merci
ngn
2

Java (JDK) , 229 octets

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

Essayez-le en ligne!

Explications

  • La carte est une carte basée sur 0.
  • La valeur renvoyée est un entier, représenté par un double. Il n'y aura jamais de partie décimale.

Code:

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

Crédits

  • -2 octets merci à Arnauld , ainsi que pour m'avoir fait réaliser que j'avais un problème avec tous mes corner-cases.
Olivier Grégoire
la source
1

Fusain , 108 octets

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

Essayez-le en ligne! Le lien est vers la version détaillée du code. Explication:

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

Liste tous les 64 carrés du tableau dans la variable de liste vide prédéfinie.

≔⟦⟦η⟧⟧δ

Faites une liste de listes dont la première entrée est une liste contenant la position de départ.

W¬№§δ±¹ζ

Répétez jusqu'à ce que la dernière entrée de la liste contienne la position finale.

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

Filtrer toutes les positions du tableau qui éloignent un chevalier de toute entrée dans la dernière entrée de la liste des listes et pousser cette liste dans la liste des listes. Cela inclut les postes précédemment visités, mais nous n'étions pas intéressés par eux de toute façon, nous nous retrouvons donc avec une première recherche approfondie du tableau pour la position finale.

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

Calculez les différences absolues de coordonnées entre les positions de début et de fin.

≡θ

Sélectionnez en fonction de la pièce d'entrée.

KI⌈ε

S'il s'agit d'un roi, imprimez la différence de coordonnées absolue maximale.

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

Si c'est une reine, imprimez 2 à moins que les deux différences soient égales ou que l'une soit nulle.

RI∨¬⌊ε²

S'il s'agit d'une tour, imprimez 2, sauf si l'une des différences est zéro.

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

Si c'est un évêque, imprimez 0 si les carrés sont de parité opposée, sinon imprimez 2 à moins que les deux différences soient égales.

NI⊖Lδ

Si c'est un chevalier, imprimez le nombre de boucles prises pour trouver la position finale.

Neil
la source
1

Japt , 67 octets

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

Essayez-le en ligne!

Ce fut toute une expérience. Je me suis beaucoup inspiré de l'excellente réponse APL . Je soupçonne qu'il y a encore beaucoup de golf possible, surtout dans le code Knight.

Les positions sont la première entrée, sous la forme [[x1,x2],[y1,y2]] . Cela devrait également fonctionner [[y1,y2],[x1,x2]]correctement. La sélection des pièces est la deuxième entrée, avec 0 = roi, 1 = reine, 2 = chevalier, 3 = tour, 4 = évêque. Notez que Knight et Rook sont échangés par rapport à la réponse APL.

Explication:

®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
la source
@ETHproductions Bonnes suggestions. Pendant que je les mettais, j'ai découvert que cela áraccourcissait [[1,2][2,1]]considérablement.
Kamil Drakari
Wow, je n'aurais jamais pensé utiliser á, sympa!
ETHproductions
Quelques suggestions de plus: Uest implicite après @, vous pouvez donc enregistrer deux octets dans la fonction chevalier. Vous pouvez également le démarrer avec @=ã ü;pour en enregistrer un autre. (L' ãastuce est aussi intelligente :-))
ETHproductions
@ETHproductions Bonne trouvaille, les moments où U est implicite sont une des choses que je n'ai pas encore complètement saisies.
Kamil Drakari