N 이동에서 기사는 어디에있을 수 있습니까?


21

APL CodeGolf 의 가을 토너먼트 3 번 홀 입니다. 나는 거기에서 문제의 원래 저자이므로 여기에 다시 게시 할 수있었습니다.


주어진:

  1. 여러 차례 (0이 없으면 움직임을 나타내지 않으면 그렇지 않으면 1이라고 가정)

  2. 8x8 체스 판에서 하나 이상의 시작 위치 목록 (예 : 0 또는 1 개의 색인화 된 좌표 또는 64 개의 연속 숫자 / 문자 또는 A1–H8 – 상태)

기사가 주어진 턴 수 이후에있을 수있는 고유 위치 목록 (입력과 같은 형식)을 어떤 순서로든 반환합니다.

  • 각 기사는 매 턴마다 움직여야하지만 같은 광장을 차지하는 여러 기사에 대해 걱정할 필요는 없습니다.

  • 기사는 position로 표시된 현재 위치를 기준으로 X로 표시된 위치로만 이동할 수 있습니다.
    기사가 움직일 수있는 곳

예 (1 인덱스 좌표)

1에서 이동 [[1,1]]: [[2,3],[3,2]]

2에서 이동 [[1,1]]: [[1,1],[1,3],[1,5],[2,4],[3,1],[3,5],[4,2],[4,4],[5,1],[5,3]]

1에서 이동 [[1,1],[5,7]]: [[2,3],[3,2],[3,6],[3,8],[4,5],[6,5],[7,6],[7,8]]

2에서 이동 [[1,1],[5,7]]: [[1,1],[1,3],[1,5],[1,7],[2,4],[2,6],[2,8],[3,1],[3,3],[3,5],[3,7],[4,2],[4,4],[4,6],[4,8],[5,1],[5,3],[5,5],[5,7],[6,4],[6,6],[6,8],[7,3],[7,7],[8,4],[8,6],[8,8]]

0에서 이동 [[3,4]]: [[3,4]]


[랭크, 파일] 대신 번호 0-63으로 체스 공간을 입력 및 출력 할 수 있습니까?
Dave

@ 데이브 물론이지? I / O와 일관성을 유지하십시오.
Adám

8
나는이 기사를 "나이트가 이동하는 곳"이라고 읽습니다
Sidney

3
말풍선 경고 : 기사의 표기법은 N입니다.
Joshua Joshua

단계 수에 1 기반 색인을 사용할 수 있습니까? 예[[1,1]], 2 -> [[2,3],[3,2]]
Zgarb

답변:


11

Wolfram Language (Mathematica) , 45 바이트

다른 솔루션이 올바르지 않기 때문에 (아래 Martin의 의견 참조) 솔루션을 게시하기로 결정했습니다.

8~KnightTourGraph~8~AdjacencyList~#&~Nest~##&

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

최고의 접두사 표기법 ...

두 개의 입력을 취합니다. 첫 번째 [1,64]는 기사의 시작 위치를 설명하는 범위의 숫자 목록이고 두 번째는 단계 수입니다.

이 솔루션은 Mathematica 내장 기능의 극한 편의에 의존합니다.

  • AdjacencyList오른쪽에 꼭짓점 목록을 가져 와서 이미 중복 된 항목을 제거하고 정렬 한 정점 목록을 반환 할 수 있습니다.
  • KnightTourGraph내장입니다. 놀랍지 않습니다.
  • Nest순서대로 인수를 취하여 오른쪽 끝을 Nest[f, expr, n]튀길 수 있습니다 .##Nest[f, ##]
  • 그리고 마지막으로, 매스 매 티카는 구문 분석 a~b~c~d~e으로 (a~b~c)~d~e더 대괄호가 필요하지 않습니다 그래서. 중위 표기법 및 평평하지 않으면 ##, 그것은 것입니다 Nest[AdjacencyList[KnightTourGraph[8, 8], #] &, #, #2]&.

1
기존 솔루션을 능가하는 데 문제가 있다고 생각하지 않습니다.
Adám

1
여러 시작 위치에서 작동합니까?
Adám

놀랄 만한! 이제 나는 이것을 어떻게 읽는지 알아 내야한다.
Dave

이것은 가상 Mthmca 골프 언어에서 17 바이트 일 것입니다.
Michael Stern

7

자바 스크립트 (ES7), 99 바이트

입 / 출력 형식 : [0 ... 63]의 제곱 인덱스 .

f=(a,n)=>n--?f([...Array(64).keys()].filter(p=>!a.every(P=>(p%8-P%8)**2^((p>>3)-(P>>3))**2^5)),n):a

테스트 사례

이 스 니펫에는 OP에서 제공하는 형식과 변환하는 두 가지 도우미 함수가 포함되어 있습니다.

방법?

다음과 같은 경우 (x, y) 에서 (X, Y) 로의 이동은 유효한 기사 이동입니다.

  • | xX | = 1| yY | = 2 또는
  • | xX | = 2| yY | = 1

절대 값을 사용하는 대신 제곱하여 다음과 같이 표현할 수 있습니다.

  • (xX) ² = 1(yY) ² = 4 또는
  • (xX) ² = 4(yY) ² = 1

14 는 XOR이 함께있을 때 5 를 제공하는 유일한 정사각형 이기 때문에 다음 과 같은 경우 유효한 기사 이동이 있습니다.

(xX) ² XOR (yY) ² XOR 5 = 0

이 공식을 보드의 각 제곱 p = 8y + x 및 각 기사 제곱 P = 8Y + X에 적용 하여 가능한 새로운 기사 대상 제곱을 추론하고이 과정을 n 번 반복적으로 반복합니다 .


5

옥타브, 69 바이트

function a=f(a,n,b=~a)for k=1:n;a=b&imdilate(a,de2bi(")0#0)"-31));end

온라인 데모!

입 / 출력은 시작 / 종료시 보드를 이진 8 * 8 매트릭스로 구성한 것입니다.

설명:

를 들어 n단계 다음 마스크 보드의 형태 팽창을 반복한다 :

01010
10001
00100
10001
01010

5

망막 , 147 102 바이트

.$
$*	
¶
 ¶
{s`((?<=N(....|.{11}|.{13})?.{7})|(?=.{8}(....|.{11}|.{13})?N))\S(?=.*	)
n
Ts`	Nn`_:N`.*¶	

온라인으로 사용해보십시오! :기사가 Ns 로 표시된 8x8 보드로 입력 하고 다음 줄의 턴 수에 대한 숫자를 입력하십시오 (9 턴 이상은 의미가 없지만 당신이 주장한다면 추가로 지원할 수 있습니다 바이트). 출력에는 추가 공백이 포함되어 있습니다. 편집 : @MartinEnder 덕분에 45 바이트가 절약되었습니다. 설명 : 첫 번째 단계는 턴 수를 단항으로 변환하지만 탭 문자를 사용하여 나중에 실수로 일치하지 않도록하고 두 번째 단계는 보드 오른쪽에 약간의 공백을 추가하여 정규 표현식이 줄 바꿈되지 않도록합니다. 모서리. 세 번째 단계는 기사의 이동 N과 관련된 모든 s와 :s를 다른 것으로 대체 N하는 n반면, 네 번째 단계는 나머지 Ns를 삭제 하고ns에서 Ns로 이동 횟수에서 1을 뺍니다. 이동 횟수가 0이 될 때까지 반복됩니다.


이것은 가장 인상적입니다. 확실히 작업에 적합한 도구는 아닙니다!
Adám

4

젤리 , 29 바이트

+þ1,2Œ!×þ1,-p`¤¤Ẏ¤Ẏ⁼%8$$ÐfQµ¡

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

인덱스가 0 인 좌표. 거의 이것이 이것이 차선 책임을 확신한다.

user202729 덕분에 -1 바이트

설명

+þ1,2Œ!×þ1,-p`¤¤Ẏ¤Ẏ⁼%8$$ÐfQµ¡  Main Link
+þ                             Addition Table (all pairs using + as combining function) with
  1,2Œ!×þ1,-p`¤¤Ẏ¤             All knight moves:
  1,2                          [1, 2]
     Œ!                        All permutations ([1, 2], [2, 1])
       ×þ                      Product Table (all pairs using × as combining function) with
         1,-p`¤                [1, 1], [1, -1], [-1, 1], [-1, -1]
         1,-                   [1, -1]
            p`                 Cartestian Product with itself
               ¤               All knight moves (in a nested array) as a nilad
                Ẏ¤             Tighten (flatten once); all knight moves in a (semi-)flat array
                        Ðf     Keep elements where
                   ⁼%8$$       The element equals itself modulo 8 (discard all elements out of the range)
                          Q    Remove Duplicates
                           µ   Start new monadic chain (essentially, terminates previous chain)
                            ¡  Repeat n times; n is implicitly the second input (right argument)

1
0 인덱스 젤리?
Adám

1
@ Adám 필터링을 쉽게 만듭니다 : P
HyperNeutrino

2
Jelly는 APL의 현재 레코드 홀더가 24 문자로 수행하기 때문에 15 바이트 미만 으로이 작업을 수행 할 수있을 것으로 기대합니다.
Adám

> = 3 $가 있으면 이전 링크로 이동하여을 참조하십시오 Ç.
user202729

예, 감사합니다.
HyperNeutrino

3

05AB1E , 27 25 바이트

2 바이트를 절약 한 Emigna 에게 감사드립니다 !

1- 인덱스 좌표를 사용합니다.

암호:

F•eĆ•SÍü‚Dí«δ+€`Ùʒ{`9‹*0›

05AB1E 인코딩을 사용합니다 . 온라인으로 사용해보십시오!

설명:

F                          # Do the following <input_1> times..
 •eĆ•SÍ                    #   Push [-1, -2, 1, 2, -1]
       ü‚                  #   Pairwise pairing: [[-1, -2], [-2, 1], [1, 2], [2, -1]]
         D                 #   Duplicate the array
          í                #   Reverse each element
           «               #   Concatenate to the previous array

이것은 우리에게 다음과 같은 배열을 제공합니다 :

[[-1, -2], [-2, 1], [1, 2], [2, -1], [-2, -1], [1, -2], [2, 1], [-1, 2]]

기사의 움직임의 델타는 어느 것입니까?

            δ+             #   Addition vectorized on both sides
              €`           #   Flatten each element
                Ù          #   Uniquify
                 ʒ         #   Keep elements which..
                  {`9‹     #     Has a maximum element smaller than 9
                      *0›  #     And a minimum element larger than 0

•eĆ•SÍü‚대신 Ƶ‡4в2ô<D(«2 바이트를 절약 할 수 있습니다 .
Emigna

@Emigna Ahh, 영리합니다. 감사합니다!
Adnan

2

파이썬 3, 105 바이트

p=lambda g,i:i and list(set(p([x+y for x in g for y in[6,10,15,17,-6,-10,-15,-17]if 0<=x+y<64],i-1)))or g

재귀를 위해 명명 된 람다를 사용해야합니다. 실격인지 확실하지 않습니다. 시작 색인을 0- 인덱스 숫자 목록으로 전달하십시오. 0은 움직임이없는 것으로 간주합니다.


2

자바 (OpenJDK 8) , 124 바이트

(m,p)->{for(;m-->0;)for(long a=p,i=p=0,j;i<64;i++)for(j=64;j-->0;)p|=(p=i%8-j%8)*p+(p=i/8-j/8)*p==5?(a>>i&1)<<j:0;return p;}

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

입출력 형식

입력 / 출력은 long(64 비트)의 비트로 표시됩니다 . 설정된 비트는 말이 있음을 의미하고, 설정되지 않은 비트는 말이 없음을 의미합니다. 예:

// [[0, 0]]
0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000001L

설명

(m, p) -> {                          // Lambda. No currying because m and p are modified
 for(;m-->0;)                        // For each move
  for(long a=p,i=p=0,j;i<64;i++)     // Declare variables, move p to a, create a new p and loop on bits of a.
   for(j=64;j-->0;)                  // Loop on bits of p.
    p |=                             // Assign to p a value.
     (p=i%8-j%8)*p+(p=i/8-j/8)*p==5  // If i -> j is a valid horse move, see Arnauld's JavaScript answer for full explanations
      ? (a>>i&1)<<j                  // Assign the presence of the horse (i-th bit of a) to the resulting board (j-th bit of p).
      : 0;                           // Else it's not a valid horse move
 return p;
}

크레딧

  • Nevay 덕분에 19 바이트가 절약되었습니다!
  • (X-x)²+(Y-y)²==5Arnauld의 트릭을 재사용 JavaScript 답변
  • 새로운 알고리즘으로 Nevay 덕분에 1 바이트 더 절약되었습니다!
  • Nevay 덕분 int[]에 64 비트로 전환하여 7 바이트를 더 절약했습니다 long.

1
169 바이트 :(m,p)->{for(;m-->0;){int i=64,a[]=p,x,y,u[]={1,3,5,9,15,19,21,23};for(p=new int[i];i-->0;)for(int z:u)if((((x=i/8+z/5-2)|(y=i%8+z%5-2))&-8)==0)p[x*8+y]|=a[i];}return p;}
Nevay

1
-1 바이트 :(m,p)->{for(int i,j,a[],x;m-->0;)for(a=p,p=new int[i=64];i-->0;)for(j=64;j-->0;)p[j]|=(x=i%8-j%8)*x+(x=i/8-j/8)*x==5?a[i]:0;return p;}
Nevay

@Nevay 감사합니다! 괄호 / 블록을 제거하는 코드를 추가하는 것은 항상 좋습니다! ;-)
Olivier Grégoire

1
–7 바이트로 대체 int[]하여 -7 바이트 long:(m,p)->{for(long i,j,a;m-->0;)for(a=p,p=i=0;i<64;i++)for(j=64;j-->0;)p|=(p=i%8-j%8)*p+(p=i/8-j/8)*p==5?(a>>i&1)<<j:0;return p;}
Nevay

건배, 나는 그런 짓을 생각조차하지 않았다! Nice job, @Nevay ;-)
Olivier Grégoire

2

젤리 , 29 28 바이트

8Rp`
“¦Ʋƈ2’D_2ṡ2+€µẎ
ÇƓ¡f1£Q

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

턴 수는 STDIN을 통해 이루어지며 사각형은 인수입니다.

이것은 @HyperNeutrino의 Jelly 솔루션과 관련이 있지만 다른 접근 방식입니다.

이제 @HyperNeutrino를 1 전체 바이트로 꺾습니다!

일부 바이트를 중단시키는 제안이 필요합니다!

링크 1 (체스 보드)

8Rp`
8R   = The list [1,2,3,4,5,6,7,8]
  p` = cartesian multiplied with itself (this results in the chessboard)

링크 2 (이동 생성)

“¦Ʋƈ2’D_2ṡ2+€µẎ
“¦Ʋƈ2’          = the number 103414301
      D         = converted into a list of digits
       _2       = subtract two from each element
         ṡ2     = overlapping pairs
           +€   = add to the list of squares
             µ  = Make sure the next part isn't treated as a right argument
              Ẏ = Tighten the list (Reducing the depth by one)

링크 3 (제곱 검사)

ÇƓ¡f1£Q
ÇƓ¡     = Repeat link #2 the requested amount of times
   f1£  = Remove everything not a member of link #1 (not on the chess board)
      Q = Make sure squares don't appear more than once

1

껍질 , 18 바이트

u!¡ṁö`fΠR2ḣ8=5ṁ□z-

1 기반 제곱 및 단계 인덱싱을 사용합니다. 온라인으로 사용해보십시오!

설명

u!¡ṁö`fΠR2ḣ8=5ṁ□z-  Implicit inputs, say P=[[1,1],[5,7]] and n=2
  ¡                 Iterate on P:
   ṁö               Map the following function, then concatenate:
                     Argument is a pair, say p=[5,7].
          ḣ8         The range [1,2,..,8]
       ΠR2           Repeat twice, take cartesian product: [[1,1],[1,2],..,[8,8]]
     `f              Filter with this predicate:
                      Argument is a pair, say q=[3,8].
                z-    Zip p and q with difference: [-2,1]
              ṁ□      Sum of squares: 5
            =5        Is it 5? Yes, so [3,8] is kept.
 !                  Take n'th step of the iteration.
u                   Remove duplicates, implicitly print.

1

R , 145 183 134 바이트

이것은 초기에 너무 골피하지 않은 Algo에 대한 주세페의 훌륭한 골프의 결과입니다 (아래 의견 참조).

function(x,n){x=x%/%8*24+x%%8
t=c(49,47,26,22)
t=c(t,-t)
for(i in 1:n)x=intersect(v<-outer(1:8,0:7*24,"+"),outer(x,t,"+"))
match(x,v)}

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

입력 및 출력은 1 ~ 64를 기준으로합니다. 1 ... 64 표기법을 사용하여 위치 벡터를 가져옵니다. 이 보드를 1 : 576 표기법, 즉 9 개의 보드로 구성된 슈퍼 보드로 매핑합니다. 이 표기법에서 각 반복마다 각 기사는 +/- 22,26,47,49만큼 움직일 수 있어야합니다. 중앙 보드에서 떨어지는 것을 제외하고 1 ... 64 표기법으로 미래 위치를 다시 반환하십시오. TIO 예제는 8x8 매트릭스를 사용하여 결과를 표시합니다.


이것은 첫 번째 테스트 사례에서 실패한 것으로 보입니다 (2 대신 4 개의 좌표를 반환합니다).
Zgarb

Zgarb를 지적 해 주셔서 감사합니다. 지금 문제를 해결했다고 생각합니다.
NofP


또는 표기법으로 대신 사용 하는 경우 148 바이트 [0...63]
주세페

1
134 바이트 , [1..64]입력 및 출력. +1이지만 이것은 훌륭한 답변입니다.
주세페
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.