몇 번 움직입니까?


16

체스 판에서 두 가지 다른 위치와 조각 유형이 주어지면 해당 조각이 한 위치에서 다른 위치로 이동하는 데 걸리는 최소 이동 수를 출력하십시오.

규칙

주어진 조각은 King, Queen, Rook, Knight 및 Bishop이 될 수 있습니다. (이 입력은 5 개의 고유 한 문자로 사용할 수 있습니다)

2 개의 위치는 편리한 형식으로 가져올 수 있습니다.

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

조각이 거기에 도달 할 수없는 경우 양의 정수 이외의 것을 출력하십시오.

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
왜 왕은 12에서 a1-h6가 필요합니까? 왕이 진단을받을 수 없습니까?
l4m2

@ l4m2, 수정 됨
Vedant Kandoi

1
@ngn, 0을 사용하여 도달 할 수 없음을 나타내면 2 개의 위치가 항상 다릅니다.
Vedant Kandoi


1
자연수의 일부 정의 (예 : ISO-80000-2)에는 0이 포함됩니다. "양의 정수"로 대체하는 것이 좋습니다.

답변:


9

자바 스크립트 (Node.js를) , 183 (180) 179 바이트

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)

온라인으로 사용해보십시오!

에지 케이스가 너무 길기 때문에 Arnauld에게 감사드립니다. 기사 테스트


@Arnauld 우물 코너 정말 비용
l4m2

마지막 max을 3 진 으로 바꾸면 바이트를 절약 할 수 있다고 생각합니다 .
얽히고 설킨

170 바이트 (내 생각에. 내 전화에 있습니다.)
Shaggy

@Shaggy는 Arnauld가 잘못 지적한 것
l4m2

6

APL (Dyalog 기본) , 117 (107) 105 (103) 98 97 95 92 89 87 바이트

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

온라인으로 사용해보십시오!

왼쪽 인수는 조각 유형 : 0 = 킹, 1 = 퀸, 2 = 루크, 3 = 기사, 4 = 비숍; 오른쪽 arg는 좌표의 2x2 행렬이며 각 행은 위치를 나타냅니다. 연결할 수없는 경우 0을 반환합니다.

|-⌿⍵ 쌍을 계산합니다 [abs (∆x), abs (∆y)]

(⍎⍺⊃... )⊣"..."목록에서 표현식을 선택합니다. 함수이면 적용됩니다 |-⌿⍵. 그것이 값이라면 (이것은 기사에게만 일어난다), 대신에 그것을 돌려줘 라|-⌿⍵

  • 왕 : ⌈/abs ∆-s의 최대 ( )

  • 여왕 : 제로 ( ~∘0)를 제거 하고 고유 ( )를 세십시오 ( )

  • 루크 : +/signa의 합 ( ) (모노 딕 ×; 0의 경우 0, 양의 경우 1)

  • 기사 : {⍺∊⍵:0⋄1+⍺∇i/⍨∨⌿2=|×/↑⍵∘.-i←,⍳8 8}/,¨⊂¨↓⍵-초기 위치에서 시작하여 최종 위치가 설정 될 때까지 기사 이동의 생성을 재귀 적으로 계산합니다. 재귀 깊이 반환

  • 주교 : 두 ∆-s의 패리티는 동일합니까? ( 2=.|⊢,와 동일 =/2|⊢) 부울 결과 (0 또는 1)에 카운트 고유 ( ≢∘∪)를 곱합니다.


나는 사랑합니다 ⍎⍺⊃. 매우 영리한.
J. Sallé

@ J.Sallé 감사
ngn

2

자바 (JDK) 229 바이트

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

온라인으로 사용해보십시오!

설명

  • 보드는 0 기반 보드입니다.
  • 반환 값은 정수이며 double로 표시됩니다. 소수점 이하 자릿수가 없습니다.

암호:

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

크레딧

  • Arnauld 덕분에 -2 바이트 덕분에 모든 코너 케이스에 문제가 있음을 알게되었습니다.

1

, 108 바이트

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

온라인으로 사용해보십시오! 링크는 자세한 버전의 코드입니다. 설명:

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

사전 정의 된 빈 목록 변수에 보드의 64 개 사각형을 모두 나열하십시오.

≔⟦⟦η⟧⟧δ

첫 번째 항목이 시작 위치를 포함하는 목록 인 목록의 목록을 작성하십시오.

W¬№§δ±¹ζ

목록의 마지막 항목에 끝 위치가 포함될 때까지 반복하십시오.

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

기사 목록 인 모든 보드 위치를 목록 목록의 마지막 항목에서 제외하고 해당 목록을 목록 목록으로 푸시하십시오. 여기에는 이전에 방문한 위치가 포함되지만 어쨌든 관심이 없었으므로 최종 위치에 대한 보드를 광범위하게 검색합니다.

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

시작 위치와 끝 위치 사이의 절대 좌표 차이를 계산하십시오.

≡θ

입력 조각을 기준으로 선택하십시오.

KI⌈ε

그것이 왕이라면 최대 절대 좌표 차이를 인쇄하십시오.

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

그것이 여왕이라면 두 차이가 같거나 하나가 0이 아닌 한 2를 인쇄하십시오.

RI∨¬⌊ε²

루크 인 경우 차이 중 하나가 0이 아닌 경우 2를 인쇄하십시오.

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

주교라면 정사각형이 반대 인 경우 0을, 그렇지 않으면 두 차이가 같지 않으면 2를 인쇄합니다.

NI⊖Lδ

기사 인 경우 종료 위치를 찾기 위해 수행 된 루프 수를 인쇄하십시오.


1

Japt , 67 바이트

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

온라인으로 사용해보십시오!

그것은 상당히 경험이었습니다. 나는 훌륭한 사람들로부터 많은 영감을 받았습니다 APL 답변 . 특히 나이트 코드에는 여전히 많은 골프가있을 것으로 생각됩니다.

위치는 형식의 첫 번째 입력 [[x1,x2],[y1,y2]]입니다. 잘 작동해야합니다.[[y1,y2],[x1,x2]]잘 . 조각 선택은 두 번째 입력이며 0 = 왕, 1 = 여왕, 2 = 기사, 3 = 루크, 4 = 비숍입니다. Knight와 Rook은 APL 답변과 비교하여 교체되었습니다.

설명:

®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 좋은 제안. 내가 그것들을 넣는 동안 나는 그것이 상당히 á단축 [[1,2][2,1]]되는 것을 알았습니다 .
카밀 Drakari

와우, 사용하지 않을 것입니다 á, 좋은 하나!
ETHproductions

몇 가지 더 제안 : U은 암시 @적이므로 기사 함수에서 2 바이트를 절약 할 수 있습니다. @=ã ü;다른 것을 저장하기 위해 시작할 수도 있습니다 . ( ã트릭도 영리하다 :-))
ETHproductions

@ETHproductions U가 암시되는 시간은 내가 아직 완전히 파악하지 못한 것 중 하나입니다.
카밀 드라 카리
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.