How many moves?











up vote
15
down vote

favorite
1












Given two different positions on a chess board and the type of piece, output the minimum number of moves it will take for that piece to go from one position to another.



Rules



The given piece can be King,Queen,Rook,Knight and Bishop. (This input can be taken as any 5 unique characters)



The 2 positions can be taken in any convenient format,



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


In case the piece cannot reach there, output anything other than a positive integer.



Examples



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









share|improve this question




















  • 1




    Why do King need 12 to a1-h6? Can't King go diag?
    – l4m2
    Nov 26 at 7:40










  • @l4m2, corrected
    – Vedant Kandoi
    Nov 26 at 7:43








  • 1




    @ngn, you can use 0 to indicate unreachability, the 2 positions will always be different.
    – Vedant Kandoi
    Nov 26 at 11:13






  • 5




    All knight distances
    – Arnauld
    Nov 26 at 15:37






  • 1




    Some definitions (such as ISO-80000-2) of natural numbers include 0. Recommend substituting with "positive integer".
    – Rogem
    Nov 28 at 13:48















up vote
15
down vote

favorite
1












Given two different positions on a chess board and the type of piece, output the minimum number of moves it will take for that piece to go from one position to another.



Rules



The given piece can be King,Queen,Rook,Knight and Bishop. (This input can be taken as any 5 unique characters)



The 2 positions can be taken in any convenient format,



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


In case the piece cannot reach there, output anything other than a positive integer.



Examples



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









share|improve this question




















  • 1




    Why do King need 12 to a1-h6? Can't King go diag?
    – l4m2
    Nov 26 at 7:40










  • @l4m2, corrected
    – Vedant Kandoi
    Nov 26 at 7:43








  • 1




    @ngn, you can use 0 to indicate unreachability, the 2 positions will always be different.
    – Vedant Kandoi
    Nov 26 at 11:13






  • 5




    All knight distances
    – Arnauld
    Nov 26 at 15:37






  • 1




    Some definitions (such as ISO-80000-2) of natural numbers include 0. Recommend substituting with "positive integer".
    – Rogem
    Nov 28 at 13:48













up vote
15
down vote

favorite
1









up vote
15
down vote

favorite
1






1





Given two different positions on a chess board and the type of piece, output the minimum number of moves it will take for that piece to go from one position to another.



Rules



The given piece can be King,Queen,Rook,Knight and Bishop. (This input can be taken as any 5 unique characters)



The 2 positions can be taken in any convenient format,



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


In case the piece cannot reach there, output anything other than a positive integer.



Examples



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









share|improve this question















Given two different positions on a chess board and the type of piece, output the minimum number of moves it will take for that piece to go from one position to another.



Rules



The given piece can be King,Queen,Rook,Knight and Bishop. (This input can be taken as any 5 unique characters)



The 2 positions can be taken in any convenient format,



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


In case the piece cannot reach there, output anything other than a positive integer.



Examples



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






code-golf chess






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 28 at 15:08

























asked Nov 26 at 6:29









Vedant Kandoi

76021




76021








  • 1




    Why do King need 12 to a1-h6? Can't King go diag?
    – l4m2
    Nov 26 at 7:40










  • @l4m2, corrected
    – Vedant Kandoi
    Nov 26 at 7:43








  • 1




    @ngn, you can use 0 to indicate unreachability, the 2 positions will always be different.
    – Vedant Kandoi
    Nov 26 at 11:13






  • 5




    All knight distances
    – Arnauld
    Nov 26 at 15:37






  • 1




    Some definitions (such as ISO-80000-2) of natural numbers include 0. Recommend substituting with "positive integer".
    – Rogem
    Nov 28 at 13:48














  • 1




    Why do King need 12 to a1-h6? Can't King go diag?
    – l4m2
    Nov 26 at 7:40










  • @l4m2, corrected
    – Vedant Kandoi
    Nov 26 at 7:43








  • 1




    @ngn, you can use 0 to indicate unreachability, the 2 positions will always be different.
    – Vedant Kandoi
    Nov 26 at 11:13






  • 5




    All knight distances
    – Arnauld
    Nov 26 at 15:37






  • 1




    Some definitions (such as ISO-80000-2) of natural numbers include 0. Recommend substituting with "positive integer".
    – Rogem
    Nov 28 at 13:48








1




1




Why do King need 12 to a1-h6? Can't King go diag?
– l4m2
Nov 26 at 7:40




Why do King need 12 to a1-h6? Can't King go diag?
– l4m2
Nov 26 at 7:40












@l4m2, corrected
– Vedant Kandoi
Nov 26 at 7:43






@l4m2, corrected
– Vedant Kandoi
Nov 26 at 7:43






1




1




@ngn, you can use 0 to indicate unreachability, the 2 positions will always be different.
– Vedant Kandoi
Nov 26 at 11:13




@ngn, you can use 0 to indicate unreachability, the 2 positions will always be different.
– Vedant Kandoi
Nov 26 at 11:13




5




5




All knight distances
– Arnauld
Nov 26 at 15:37




All knight distances
– Arnauld
Nov 26 at 15:37




1




1




Some definitions (such as ISO-80000-2) of natural numbers include 0. Recommend substituting with "positive integer".
– Rogem
Nov 28 at 13:48




Some definitions (such as ISO-80000-2) of natural numbers include 0. Recommend substituting with "positive integer".
– Rogem
Nov 28 at 13:48










5 Answers
5






active

oldest

votes

















up vote
9
down vote














JavaScript (Node.js), 183 180 179 bytes





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)


Try it online!



So long for edge case, thank Arnauld for checking. Knight test






share|improve this answer























  • @Arnauld Well corner really cost
    – l4m2
    Nov 26 at 14:02










  • I think you might be able to save a byte by replacing the last max with a ternary.
    – Shaggy
    Nov 26 at 14:07










  • 170 bytes (I think. I'm on my phone.)
    – Shaggy
    Nov 26 at 14:16










  • @Shaggy was what Arnauld pointn that wrong
    – l4m2
    Nov 26 at 14:18


















up vote
6
down vote














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





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


Try it online!



left arg is piece type: 0=king, 1=queen, 2=rook, 3=knight, 4=bishop; right arg is a 2x2 matrix of coords, each row representing a position; returns 0 for unreachable



|-⌿⍵ computes the pair [abs(∆x),abs(∆y)]



(⍎⍺⊃...)⊣ chooses an expression from the "..." list; if it's a function, it's applied to |-⌿⍵; if it's a value (this happens only for a knight), makes sure to return it instead of |-⌿⍵




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


  • queen: remove zeroes (~∘0) and count () unique ()


  • rook: sum (+/) of signa (monadic ×; 0 for 0, 1 for positive)


  • knight: {⍺∊⍵:0⋄1+⍺∇i/⍨∨⌿2=|×/↑⍵∘.-i←,⍳8 8}/,¨⊂¨↓⍵ - start with the initial position and recursively compute generations of knight moves until the final position is in the set; return recursion depth


  • bishop: are the parities of the two ∆-s equal? (2=.|⊢, equivalent to =/2|⊢) multiply the boolean result (0 or 1) by the count-unique (≢∘∪)







share|improve this answer























  • I love the ⍎⍺⊃. Very clever.
    – J. Sallé
    Nov 26 at 17:47










  • @J.Sallé thanks
    – ngn
    Nov 27 at 6:43


















up vote
2
down vote














Java (JDK), 229 bytes





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


Try it online!



Explanations




  • The board is a 0-based board.

  • The returned-value is an integer, represented as a double. There will never be any decimal part.


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


Credits




  • -2 bytes thanks to Arnauld, as well as for making me realize that I had an issue with all my corner-cases.






share|improve this answer






























    up vote
    1
    down vote














    Charcoal, 108 bytes



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


    Try it online! Link is to verbose version of code. Explanation:



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


    List all the 64 squares of the board into the predefined empty list variable.



    ≔⟦⟦η⟧⟧δ


    Make a list of lists whose first entry is a list containing the start position.



    W¬№§δ±¹ζ


    Repeat until the last entry of the list contains the end position.



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


    Filter all the board positions that are a knight's move away from any entry in the last entry of the list of lists and push that list to the list of lists. This includes positions previously visited but we weren't interested in them anyway, so we end up with a breadth first search of the board for the end position.



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


    Calculate the absolute coordinate differences between the start and end positions.



    ≡θ


    Select based on the input piece.



    KI⌈ε


    If it's a king then print the maximum absolute coordinate difference.



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


    If it's a queen then print 2 unless the two differences are equal or one is zero.



    RI∨¬⌊ε²


    If it's a rook then print 2 unless one of the differences is zero.



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


    If it's a bishop then print 0 if the squares are of opposite parity otherwise print 2 unless the two differences are equal.



    NI⊖Lδ


    If it's a knight then print the number of loops taken to find the end position.






    share|improve this answer




























      up vote
      1
      down vote














      Japt, 67 bytes



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


      Try it online!



      That was quite an experience. I took a lot of inspiration from the excellent APL Answer. I suspect there is a lot of golfing still possible especially in the Knight code.



      The positions are the first input, in the form [[x1,x2],[y1,y2]]. It should work fine on [[y1,y2],[x1,x2]] as well. Piece selection is the second input, with 0=king, 1=queen, 2=knight, 3=rook, 4=bishop. Note that Knight and Rook are swapped compared to the APL answer.



      Explanation:



      ®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





      share|improve this answer























      • @ETHproductions Good suggestions. While I was putting them in I found out that á worked to shorten [[1,2][2,1]] considerably.
        – Kamil Drakari
        Nov 28 at 23:56










      • Wow, never would have thought to use á, nice one!
        – ETHproductions
        Nov 29 at 1:52










      • A couple more suggestions: U is implicit after @, so you can save two bytes in the knight function. You can also start it out with @=ã ü; to save another. (The ã trick is clever too :-) )
        – ETHproductions
        Nov 29 at 2:09












      • @ETHproductions Good find, the times when U is implied are one of the things I haven't fully grasped yet.
        – Kamil Drakari
        Nov 29 at 3:11











      Your Answer





      StackExchange.ifUsing("editor", function () {
      return StackExchange.using("mathjaxEditing", function () {
      StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
      StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
      });
      });
      }, "mathjax-editing");

      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "200"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      convertImagesToLinks: false,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodegolf.stackexchange.com%2fquestions%2f176567%2fhow-many-moves%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      5 Answers
      5






      active

      oldest

      votes








      5 Answers
      5






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      9
      down vote














      JavaScript (Node.js), 183 180 179 bytes





      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)


      Try it online!



      So long for edge case, thank Arnauld for checking. Knight test






      share|improve this answer























      • @Arnauld Well corner really cost
        – l4m2
        Nov 26 at 14:02










      • I think you might be able to save a byte by replacing the last max with a ternary.
        – Shaggy
        Nov 26 at 14:07










      • 170 bytes (I think. I'm on my phone.)
        – Shaggy
        Nov 26 at 14:16










      • @Shaggy was what Arnauld pointn that wrong
        – l4m2
        Nov 26 at 14:18















      up vote
      9
      down vote














      JavaScript (Node.js), 183 180 179 bytes





      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)


      Try it online!



      So long for edge case, thank Arnauld for checking. Knight test






      share|improve this answer























      • @Arnauld Well corner really cost
        – l4m2
        Nov 26 at 14:02










      • I think you might be able to save a byte by replacing the last max with a ternary.
        – Shaggy
        Nov 26 at 14:07










      • 170 bytes (I think. I'm on my phone.)
        – Shaggy
        Nov 26 at 14:16










      • @Shaggy was what Arnauld pointn that wrong
        – l4m2
        Nov 26 at 14:18













      up vote
      9
      down vote










      up vote
      9
      down vote










      JavaScript (Node.js), 183 180 179 bytes





      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)


      Try it online!



      So long for edge case, thank Arnauld for checking. Knight test






      share|improve this answer















      JavaScript (Node.js), 183 180 179 bytes





      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)


      Try it online!



      So long for edge case, thank Arnauld for checking. Knight test







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 29 at 17:56

























      answered Nov 26 at 11:18









      l4m2

      4,4711634




      4,4711634












      • @Arnauld Well corner really cost
        – l4m2
        Nov 26 at 14:02










      • I think you might be able to save a byte by replacing the last max with a ternary.
        – Shaggy
        Nov 26 at 14:07










      • 170 bytes (I think. I'm on my phone.)
        – Shaggy
        Nov 26 at 14:16










      • @Shaggy was what Arnauld pointn that wrong
        – l4m2
        Nov 26 at 14:18


















      • @Arnauld Well corner really cost
        – l4m2
        Nov 26 at 14:02










      • I think you might be able to save a byte by replacing the last max with a ternary.
        – Shaggy
        Nov 26 at 14:07










      • 170 bytes (I think. I'm on my phone.)
        – Shaggy
        Nov 26 at 14:16










      • @Shaggy was what Arnauld pointn that wrong
        – l4m2
        Nov 26 at 14:18
















      @Arnauld Well corner really cost
      – l4m2
      Nov 26 at 14:02




      @Arnauld Well corner really cost
      – l4m2
      Nov 26 at 14:02












      I think you might be able to save a byte by replacing the last max with a ternary.
      – Shaggy
      Nov 26 at 14:07




      I think you might be able to save a byte by replacing the last max with a ternary.
      – Shaggy
      Nov 26 at 14:07












      170 bytes (I think. I'm on my phone.)
      – Shaggy
      Nov 26 at 14:16




      170 bytes (I think. I'm on my phone.)
      – Shaggy
      Nov 26 at 14:16












      @Shaggy was what Arnauld pointn that wrong
      – l4m2
      Nov 26 at 14:18




      @Shaggy was what Arnauld pointn that wrong
      – l4m2
      Nov 26 at 14:18










      up vote
      6
      down vote














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





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


      Try it online!



      left arg is piece type: 0=king, 1=queen, 2=rook, 3=knight, 4=bishop; right arg is a 2x2 matrix of coords, each row representing a position; returns 0 for unreachable



      |-⌿⍵ computes the pair [abs(∆x),abs(∆y)]



      (⍎⍺⊃...)⊣ chooses an expression from the "..." list; if it's a function, it's applied to |-⌿⍵; if it's a value (this happens only for a knight), makes sure to return it instead of |-⌿⍵




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


      • queen: remove zeroes (~∘0) and count () unique ()


      • rook: sum (+/) of signa (monadic ×; 0 for 0, 1 for positive)


      • knight: {⍺∊⍵:0⋄1+⍺∇i/⍨∨⌿2=|×/↑⍵∘.-i←,⍳8 8}/,¨⊂¨↓⍵ - start with the initial position and recursively compute generations of knight moves until the final position is in the set; return recursion depth


      • bishop: are the parities of the two ∆-s equal? (2=.|⊢, equivalent to =/2|⊢) multiply the boolean result (0 or 1) by the count-unique (≢∘∪)







      share|improve this answer























      • I love the ⍎⍺⊃. Very clever.
        – J. Sallé
        Nov 26 at 17:47










      • @J.Sallé thanks
        – ngn
        Nov 27 at 6:43















      up vote
      6
      down vote














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





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


      Try it online!



      left arg is piece type: 0=king, 1=queen, 2=rook, 3=knight, 4=bishop; right arg is a 2x2 matrix of coords, each row representing a position; returns 0 for unreachable



      |-⌿⍵ computes the pair [abs(∆x),abs(∆y)]



      (⍎⍺⊃...)⊣ chooses an expression from the "..." list; if it's a function, it's applied to |-⌿⍵; if it's a value (this happens only for a knight), makes sure to return it instead of |-⌿⍵




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


      • queen: remove zeroes (~∘0) and count () unique ()


      • rook: sum (+/) of signa (monadic ×; 0 for 0, 1 for positive)


      • knight: {⍺∊⍵:0⋄1+⍺∇i/⍨∨⌿2=|×/↑⍵∘.-i←,⍳8 8}/,¨⊂¨↓⍵ - start with the initial position and recursively compute generations of knight moves until the final position is in the set; return recursion depth


      • bishop: are the parities of the two ∆-s equal? (2=.|⊢, equivalent to =/2|⊢) multiply the boolean result (0 or 1) by the count-unique (≢∘∪)







      share|improve this answer























      • I love the ⍎⍺⊃. Very clever.
        – J. Sallé
        Nov 26 at 17:47










      • @J.Sallé thanks
        – ngn
        Nov 27 at 6:43













      up vote
      6
      down vote










      up vote
      6
      down vote










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





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


      Try it online!



      left arg is piece type: 0=king, 1=queen, 2=rook, 3=knight, 4=bishop; right arg is a 2x2 matrix of coords, each row representing a position; returns 0 for unreachable



      |-⌿⍵ computes the pair [abs(∆x),abs(∆y)]



      (⍎⍺⊃...)⊣ chooses an expression from the "..." list; if it's a function, it's applied to |-⌿⍵; if it's a value (this happens only for a knight), makes sure to return it instead of |-⌿⍵




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


      • queen: remove zeroes (~∘0) and count () unique ()


      • rook: sum (+/) of signa (monadic ×; 0 for 0, 1 for positive)


      • knight: {⍺∊⍵:0⋄1+⍺∇i/⍨∨⌿2=|×/↑⍵∘.-i←,⍳8 8}/,¨⊂¨↓⍵ - start with the initial position and recursively compute generations of knight moves until the final position is in the set; return recursion depth


      • bishop: are the parities of the two ∆-s equal? (2=.|⊢, equivalent to =/2|⊢) multiply the boolean result (0 or 1) by the count-unique (≢∘∪)







      share|improve this answer















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





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


      Try it online!



      left arg is piece type: 0=king, 1=queen, 2=rook, 3=knight, 4=bishop; right arg is a 2x2 matrix of coords, each row representing a position; returns 0 for unreachable



      |-⌿⍵ computes the pair [abs(∆x),abs(∆y)]



      (⍎⍺⊃...)⊣ chooses an expression from the "..." list; if it's a function, it's applied to |-⌿⍵; if it's a value (this happens only for a knight), makes sure to return it instead of |-⌿⍵




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


      • queen: remove zeroes (~∘0) and count () unique ()


      • rook: sum (+/) of signa (monadic ×; 0 for 0, 1 for positive)


      • knight: {⍺∊⍵:0⋄1+⍺∇i/⍨∨⌿2=|×/↑⍵∘.-i←,⍳8 8}/,¨⊂¨↓⍵ - start with the initial position and recursively compute generations of knight moves until the final position is in the set; return recursion depth


      • bishop: are the parities of the two ∆-s equal? (2=.|⊢, equivalent to =/2|⊢) multiply the boolean result (0 or 1) by the count-unique (≢∘∪)








      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 27 at 6:43

























      answered Nov 26 at 11:49









      ngn

      6,53312459




      6,53312459












      • I love the ⍎⍺⊃. Very clever.
        – J. Sallé
        Nov 26 at 17:47










      • @J.Sallé thanks
        – ngn
        Nov 27 at 6:43


















      • I love the ⍎⍺⊃. Very clever.
        – J. Sallé
        Nov 26 at 17:47










      • @J.Sallé thanks
        – ngn
        Nov 27 at 6:43
















      I love the ⍎⍺⊃. Very clever.
      – J. Sallé
      Nov 26 at 17:47




      I love the ⍎⍺⊃. Very clever.
      – J. Sallé
      Nov 26 at 17:47












      @J.Sallé thanks
      – ngn
      Nov 27 at 6:43




      @J.Sallé thanks
      – ngn
      Nov 27 at 6:43










      up vote
      2
      down vote














      Java (JDK), 229 bytes





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


      Try it online!



      Explanations




      • The board is a 0-based board.

      • The returned-value is an integer, represented as a double. There will never be any decimal part.


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


      Credits




      • -2 bytes thanks to Arnauld, as well as for making me realize that I had an issue with all my corner-cases.






      share|improve this answer



























        up vote
        2
        down vote














        Java (JDK), 229 bytes





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


        Try it online!



        Explanations




        • The board is a 0-based board.

        • The returned-value is an integer, represented as a double. There will never be any decimal part.


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


        Credits




        • -2 bytes thanks to Arnauld, as well as for making me realize that I had an issue with all my corner-cases.






        share|improve this answer

























          up vote
          2
          down vote










          up vote
          2
          down vote










          Java (JDK), 229 bytes





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


          Try it online!



          Explanations




          • The board is a 0-based board.

          • The returned-value is an integer, represented as a double. There will never be any decimal part.


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


          Credits




          • -2 bytes thanks to Arnauld, as well as for making me realize that I had an issue with all my corner-cases.






          share|improve this answer















          Java (JDK), 229 bytes





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


          Try it online!



          Explanations




          • The board is a 0-based board.

          • The returned-value is an integer, represented as a double. There will never be any decimal part.


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


          Credits




          • -2 bytes thanks to Arnauld, as well as for making me realize that I had an issue with all my corner-cases.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 28 at 16:03

























          answered Nov 26 at 16:27









          Olivier Grégoire

          8,28711842




          8,28711842






















              up vote
              1
              down vote














              Charcoal, 108 bytes



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


              Try it online! Link is to verbose version of code. Explanation:



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


              List all the 64 squares of the board into the predefined empty list variable.



              ≔⟦⟦η⟧⟧δ


              Make a list of lists whose first entry is a list containing the start position.



              W¬№§δ±¹ζ


              Repeat until the last entry of the list contains the end position.



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


              Filter all the board positions that are a knight's move away from any entry in the last entry of the list of lists and push that list to the list of lists. This includes positions previously visited but we weren't interested in them anyway, so we end up with a breadth first search of the board for the end position.



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


              Calculate the absolute coordinate differences between the start and end positions.



              ≡θ


              Select based on the input piece.



              KI⌈ε


              If it's a king then print the maximum absolute coordinate difference.



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


              If it's a queen then print 2 unless the two differences are equal or one is zero.



              RI∨¬⌊ε²


              If it's a rook then print 2 unless one of the differences is zero.



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


              If it's a bishop then print 0 if the squares are of opposite parity otherwise print 2 unless the two differences are equal.



              NI⊖Lδ


              If it's a knight then print the number of loops taken to find the end position.






              share|improve this answer

























                up vote
                1
                down vote














                Charcoal, 108 bytes



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


                Try it online! Link is to verbose version of code. Explanation:



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


                List all the 64 squares of the board into the predefined empty list variable.



                ≔⟦⟦η⟧⟧δ


                Make a list of lists whose first entry is a list containing the start position.



                W¬№§δ±¹ζ


                Repeat until the last entry of the list contains the end position.



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


                Filter all the board positions that are a knight's move away from any entry in the last entry of the list of lists and push that list to the list of lists. This includes positions previously visited but we weren't interested in them anyway, so we end up with a breadth first search of the board for the end position.



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


                Calculate the absolute coordinate differences between the start and end positions.



                ≡θ


                Select based on the input piece.



                KI⌈ε


                If it's a king then print the maximum absolute coordinate difference.



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


                If it's a queen then print 2 unless the two differences are equal or one is zero.



                RI∨¬⌊ε²


                If it's a rook then print 2 unless one of the differences is zero.



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


                If it's a bishop then print 0 if the squares are of opposite parity otherwise print 2 unless the two differences are equal.



                NI⊖Lδ


                If it's a knight then print the number of loops taken to find the end position.






                share|improve this answer























                  up vote
                  1
                  down vote










                  up vote
                  1
                  down vote










                  Charcoal, 108 bytes



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


                  Try it online! Link is to verbose version of code. Explanation:



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


                  List all the 64 squares of the board into the predefined empty list variable.



                  ≔⟦⟦η⟧⟧δ


                  Make a list of lists whose first entry is a list containing the start position.



                  W¬№§δ±¹ζ


                  Repeat until the last entry of the list contains the end position.



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


                  Filter all the board positions that are a knight's move away from any entry in the last entry of the list of lists and push that list to the list of lists. This includes positions previously visited but we weren't interested in them anyway, so we end up with a breadth first search of the board for the end position.



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


                  Calculate the absolute coordinate differences between the start and end positions.



                  ≡θ


                  Select based on the input piece.



                  KI⌈ε


                  If it's a king then print the maximum absolute coordinate difference.



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


                  If it's a queen then print 2 unless the two differences are equal or one is zero.



                  RI∨¬⌊ε²


                  If it's a rook then print 2 unless one of the differences is zero.



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


                  If it's a bishop then print 0 if the squares are of opposite parity otherwise print 2 unless the two differences are equal.



                  NI⊖Lδ


                  If it's a knight then print the number of loops taken to find the end position.






                  share|improve this answer













                  Charcoal, 108 bytes



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


                  Try it online! Link is to verbose version of code. Explanation:



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


                  List all the 64 squares of the board into the predefined empty list variable.



                  ≔⟦⟦η⟧⟧δ


                  Make a list of lists whose first entry is a list containing the start position.



                  W¬№§δ±¹ζ


                  Repeat until the last entry of the list contains the end position.



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


                  Filter all the board positions that are a knight's move away from any entry in the last entry of the list of lists and push that list to the list of lists. This includes positions previously visited but we weren't interested in them anyway, so we end up with a breadth first search of the board for the end position.



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


                  Calculate the absolute coordinate differences between the start and end positions.



                  ≡θ


                  Select based on the input piece.



                  KI⌈ε


                  If it's a king then print the maximum absolute coordinate difference.



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


                  If it's a queen then print 2 unless the two differences are equal or one is zero.



                  RI∨¬⌊ε²


                  If it's a rook then print 2 unless one of the differences is zero.



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


                  If it's a bishop then print 0 if the squares are of opposite parity otherwise print 2 unless the two differences are equal.



                  NI⊖Lδ


                  If it's a knight then print the number of loops taken to find the end position.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 27 at 19:12









                  Neil

                  78.5k744175




                  78.5k744175






















                      up vote
                      1
                      down vote














                      Japt, 67 bytes



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


                      Try it online!



                      That was quite an experience. I took a lot of inspiration from the excellent APL Answer. I suspect there is a lot of golfing still possible especially in the Knight code.



                      The positions are the first input, in the form [[x1,x2],[y1,y2]]. It should work fine on [[y1,y2],[x1,x2]] as well. Piece selection is the second input, with 0=king, 1=queen, 2=knight, 3=rook, 4=bishop. Note that Knight and Rook are swapped compared to the APL answer.



                      Explanation:



                      ®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





                      share|improve this answer























                      • @ETHproductions Good suggestions. While I was putting them in I found out that á worked to shorten [[1,2][2,1]] considerably.
                        – Kamil Drakari
                        Nov 28 at 23:56










                      • Wow, never would have thought to use á, nice one!
                        – ETHproductions
                        Nov 29 at 1:52










                      • A couple more suggestions: U is implicit after @, so you can save two bytes in the knight function. You can also start it out with @=ã ü; to save another. (The ã trick is clever too :-) )
                        – ETHproductions
                        Nov 29 at 2:09












                      • @ETHproductions Good find, the times when U is implied are one of the things I haven't fully grasped yet.
                        – Kamil Drakari
                        Nov 29 at 3:11















                      up vote
                      1
                      down vote














                      Japt, 67 bytes



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


                      Try it online!



                      That was quite an experience. I took a lot of inspiration from the excellent APL Answer. I suspect there is a lot of golfing still possible especially in the Knight code.



                      The positions are the first input, in the form [[x1,x2],[y1,y2]]. It should work fine on [[y1,y2],[x1,x2]] as well. Piece selection is the second input, with 0=king, 1=queen, 2=knight, 3=rook, 4=bishop. Note that Knight and Rook are swapped compared to the APL answer.



                      Explanation:



                      ®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





                      share|improve this answer























                      • @ETHproductions Good suggestions. While I was putting them in I found out that á worked to shorten [[1,2][2,1]] considerably.
                        – Kamil Drakari
                        Nov 28 at 23:56










                      • Wow, never would have thought to use á, nice one!
                        – ETHproductions
                        Nov 29 at 1:52










                      • A couple more suggestions: U is implicit after @, so you can save two bytes in the knight function. You can also start it out with @=ã ü; to save another. (The ã trick is clever too :-) )
                        – ETHproductions
                        Nov 29 at 2:09












                      • @ETHproductions Good find, the times when U is implied are one of the things I haven't fully grasped yet.
                        – Kamil Drakari
                        Nov 29 at 3:11













                      up vote
                      1
                      down vote










                      up vote
                      1
                      down vote










                      Japt, 67 bytes



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


                      Try it online!



                      That was quite an experience. I took a lot of inspiration from the excellent APL Answer. I suspect there is a lot of golfing still possible especially in the Knight code.



                      The positions are the first input, in the form [[x1,x2],[y1,y2]]. It should work fine on [[y1,y2],[x1,x2]] as well. Piece selection is the second input, with 0=king, 1=queen, 2=knight, 3=rook, 4=bishop. Note that Knight and Rook are swapped compared to the APL answer.



                      Explanation:



                      ®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





                      share|improve this answer















                      Japt, 67 bytes



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


                      Try it online!



                      That was quite an experience. I took a lot of inspiration from the excellent APL Answer. I suspect there is a lot of golfing still possible especially in the Knight code.



                      The positions are the first input, in the form [[x1,x2],[y1,y2]]. It should work fine on [[y1,y2],[x1,x2]] as well. Piece selection is the second input, with 0=king, 1=queen, 2=knight, 3=rook, 4=bishop. Note that Knight and Rook are swapped compared to the APL answer.



                      Explanation:



                      ®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






                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited Nov 29 at 3:05

























                      answered Nov 28 at 16:34









                      Kamil Drakari

                      2,636416




                      2,636416












                      • @ETHproductions Good suggestions. While I was putting them in I found out that á worked to shorten [[1,2][2,1]] considerably.
                        – Kamil Drakari
                        Nov 28 at 23:56










                      • Wow, never would have thought to use á, nice one!
                        – ETHproductions
                        Nov 29 at 1:52










                      • A couple more suggestions: U is implicit after @, so you can save two bytes in the knight function. You can also start it out with @=ã ü; to save another. (The ã trick is clever too :-) )
                        – ETHproductions
                        Nov 29 at 2:09












                      • @ETHproductions Good find, the times when U is implied are one of the things I haven't fully grasped yet.
                        – Kamil Drakari
                        Nov 29 at 3:11


















                      • @ETHproductions Good suggestions. While I was putting them in I found out that á worked to shorten [[1,2][2,1]] considerably.
                        – Kamil Drakari
                        Nov 28 at 23:56










                      • Wow, never would have thought to use á, nice one!
                        – ETHproductions
                        Nov 29 at 1:52










                      • A couple more suggestions: U is implicit after @, so you can save two bytes in the knight function. You can also start it out with @=ã ü; to save another. (The ã trick is clever too :-) )
                        – ETHproductions
                        Nov 29 at 2:09












                      • @ETHproductions Good find, the times when U is implied are one of the things I haven't fully grasped yet.
                        – Kamil Drakari
                        Nov 29 at 3:11
















                      @ETHproductions Good suggestions. While I was putting them in I found out that á worked to shorten [[1,2][2,1]] considerably.
                      – Kamil Drakari
                      Nov 28 at 23:56




                      @ETHproductions Good suggestions. While I was putting them in I found out that á worked to shorten [[1,2][2,1]] considerably.
                      – Kamil Drakari
                      Nov 28 at 23:56












                      Wow, never would have thought to use á, nice one!
                      – ETHproductions
                      Nov 29 at 1:52




                      Wow, never would have thought to use á, nice one!
                      – ETHproductions
                      Nov 29 at 1:52












                      A couple more suggestions: U is implicit after @, so you can save two bytes in the knight function. You can also start it out with @=ã ü; to save another. (The ã trick is clever too :-) )
                      – ETHproductions
                      Nov 29 at 2:09






                      A couple more suggestions: U is implicit after @, so you can save two bytes in the knight function. You can also start it out with @=ã ü; to save another. (The ã trick is clever too :-) )
                      – ETHproductions
                      Nov 29 at 2:09














                      @ETHproductions Good find, the times when U is implied are one of the things I haven't fully grasped yet.
                      – Kamil Drakari
                      Nov 29 at 3:11




                      @ETHproductions Good find, the times when U is implied are one of the things I haven't fully grasped yet.
                      – Kamil Drakari
                      Nov 29 at 3:11


















                      draft saved

                      draft discarded




















































                      If this is an answer to a challenge…




                      • …Be sure to follow the challenge specification. However, please refrain from exploiting obvious loopholes. Answers abusing any of the standard loopholes are considered invalid. If you think a specification is unclear or underspecified, comment on the question instead.


                      • …Try to optimize your score. For instance, answers to code-golf challenges should attempt to be as short as possible. You can always include a readable version of the code in addition to the competitive one.
                        Explanations of your answer make it more interesting to read and are very much encouraged.


                      • …Include a short header which indicates the language(s) of your code and its score, as defined by the challenge.



                      More generally…




                      • …Please make sure to answer the question and provide sufficient detail.


                      • …Avoid asking for help, clarification or responding to other answers (use comments instead).






                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodegolf.stackexchange.com%2fquestions%2f176567%2fhow-many-moves%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

                      ComboBox Display Member on multiple fields

                      Is it possible to collect Nectar points via Trainline?