Hiệp sĩ có thể ở đâu trong N di chuyển?


21

Đây là Hole-3 từ Giải đấu mùa thu của APL CodeGolf . Tôi là tác giả ban đầu của vấn đề ở đó, và do đó được phép đăng lại ở đây.


Được:

  1. một số lượt (vui lòng nêu rõ nếu không có chuyển động nào là 0, nếu không chúng tôi sẽ cho rằng nó được gọi là 1) và

  2. danh sách một hoặc nhiều vị trí bắt đầu (dưới bất kỳ hình thức nào, ví dụ 0 hoặc 1 tọa độ được lập chỉ mục hoặc 64 số / ký tự liên tiếp hoặc A1 Thẻ H8 - trạng thái), trên bàn cờ 8-8,

return (theo bất kỳ thứ tự nào) danh sách các vị trí duy nhất (có cùng định dạng với đầu vào) mà hiệp sĩ có thể có sau số lượt đã cho.

  • Mỗi hiệp sĩ phải di chuyển với mỗi lượt, nhưng bạn không phải lo lắng về việc nhiều hiệp sĩ chiếm cùng một hình vuông.

  • Một hiệp sĩ chỉ có thể di chuyển đến các vị trí được đánh dấu X so với vị trí hiện tại của nó, được đánh dấu bằng ♞:
    nơi một hiệp sĩ có thể di chuyển

Ví dụ (tọa độ 1 chỉ mục)

1chuyển từ [[1,1]]: [[2,3],[3,2]]

2chuyển từ [[1,1]]: [[1,1],[1,3],[1,5],[2,4],[3,1],[3,5],[4,2],[4,4],[5,1],[5,3]]

1chuyển từ [[1,1],[5,7]]: [[2,3],[3,2],[3,6],[3,8],[4,5],[6,5],[7,6],[7,8]]

2chuyển từ [[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]]

0chuyển từ [[3,4]]: [[3,4]]


Không gian cờ có thể được nhập và xuất bằng cách đánh số 0-63 thay vì [thứ hạng, tệp]?
Dave

@Dave Chắc chắn, tại sao không? Chỉ cần phù hợp với I / O.
Adám

8
Tôi thề tôi đã đọc HNQ này là "Nơi hiệp sĩ ở trong Ni di chuyển"
Sidney

3
Pun alert: ký hiệu cho hiệp sĩ là N.
Joshua

Chúng ta có thể sử dụng lập chỉ mục 1 dựa trên số bước không? Ví dụ:[[1,1]], 2 -> [[2,3],[3,2]]
Zgarb

Câu trả lời:


11

Ngôn ngữ Wolfram (Mathicala) , 45 byte

Vì giải pháp khác không chính xác (xem bình luận của Martin bên dưới), nên tôi quyết định đăng giải pháp của mình:

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

Hãy thử trực tuyến!

Ký hiệu cuối cùng ...

Có 2 đầu vào, đầu tiên là danh sách các số trong phạm vi [1,64]mô tả các vị trí bắt đầu của hiệp sĩ, số thứ hai là số bước.

Giải pháp này dựa trên sự tiện lợi cao của các hàm dựng sẵn Mathicala:

  • AdjacencyListcó thể lấy một danh sách các đỉnh ở phía bên phải của nó và trả về một danh sách các đỉnh liền kề với bất kỳ đỉnh nào, đã được loại bỏ trùng lặp và sắp xếp .
  • KnightTourGraphlà một nội dung. Không bất ngờ.
  • Nestlấy các đối số theo thứ tự Nest[f, expr, n], mà chúng ta có thể chia ra ##phía bên phải của nó là Nest[f, ##].
  • Và cuối cùng, Mathicala phân tích a~b~c~d~enhư (a~b~c)~d~e, vì vậy không cần khung vuông. Nếu không có ký hiệu infix và flatten ##, nó sẽ được Nest[AdjacencyList[KnightTourGraph[8, 8], #] &, #, #2]&.

1
Tôi không nghĩ có gì sai khi vượt qua một giải pháp hiện có.
Adám

1
Điều này có làm việc với nhiều vị trí bắt đầu?
Adám

Kinh ngạc! Bây giờ tôi cần tìm hiểu làm thế nào ti đọc được điều này ...
Dave

Đây có lẽ sẽ là 17 byte trong ngôn ngữ chơi gôn Mippyca giả thuyết.
Michael Stern

7

JavaScript (ES7), 99 byte

Định dạng đầu vào / đầu ra: chỉ số hình vuông trong [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

Các trường hợp thử nghiệm

Đoạn mã này bao gồm hai chức năng trợ giúp để dịch từ và sang định dạng do OP cung cấp.

Làm sao?

Di chuyển từ (x, y) sang (X, Y) là di chuyển hiệp sĩ hợp lệ nếu chúng ta có:

  • | xX | = 1| yY | = 2 , hoặc
  • | xX | = 2| yY | = 1

Bằng cách bình phương thay vì sử dụng các giá trị tuyệt đối, điều này có thể được biểu thị như sau:

  • (xX) ² = 1(yY) ² = 4 , hoặc
  • (xX) ² = 4(yY) ² = 1

Bởi vì 14 là các ô vuông hoàn hảo duy nhất cho 5 khi XOR kết hợp với nhau, chúng tôi có một hiệp sĩ hợp lệ nếu:

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

Chúng tôi áp dụng công thức này cho mỗi ô vuông p = 8y + x trên bảng và mỗi ô vuông hiệp sĩ P = 8Y + X để suy ra các ô vuông mục tiêu hiệp sĩ mới có thể, và lặp lại quy trình này n lần.


5

Octave, 69 byte

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

Demo trực tuyến!

Đầu vào / đầu ra là cấu hình của bảng khi bắt đầu / kết thúc dưới dạng ma trận 8 * 8 nhị phân.

Giải trình:

Đối với ncác bước lặp lại sự giãn nở hình thái của bảng với mặt nạ sau:

01010
10001
00100
10001
01010

5

Võng mạc , 147 102 byte

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

Hãy thử trực tuyến! Có đầu vào là một bảng 8 x 8 :với các hiệp sĩ được đánh dấu bằng Ns, với một chữ số cho số lượt trên dòng tiếp theo (sẽ không có ý nghĩa gì khi có nhiều hơn 9 lượt, nhưng nếu bạn khăng khăng tôi có thể hỗ trợ thêm byte). Lưu ý rằng đầu ra chứa thêm khoảng trắng. Chỉnh sửa: Đã lưu 45 byte nhờ @MartinEnder. Giải thích: Giai đoạn đầu tiên chuyển đổi số lượt thành đơn vị, nhưng sử dụng các ký tự tab để chúng không bị khớp sau đó một cách tình cờ, trong khi giai đoạn thứ hai thêm một số khoảng trắng ở bên phải của bảng để ngăn các biểu thức kết thúc cạnh. Giai đoạn thứ ba thay thế tất cả các Ns và :một hiệp sĩ rời khỏi Nmột ntrong khi giai đoạn thứ tư xóa mọi Ns còn lại , thay đổins đến Ns và trừ 1 từ số lần di chuyển. Điều này lặp lại cho đến khi số lượng di chuyển bằng không.


Điều này là ấn tượng nhất. Chắc chắn không phải là công cụ phù hợp cho công việc!
Adám

4

Thạch , 29 byte

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

Hãy thử trực tuyến!

Tọa độ 0 chỉ số. Hầu như chắc chắn đây là tối ưu.

-1 byte nhờ người dùng202729

Giải trình

+þ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
Thạch 0 chỉ số?
Adám

1
@ Adám Làm cho việc lọc dễ dàng hơn: P
HyperNeutrino

2
Tôi hy vọng Jelly có thể thực hiện việc này dưới 15 byte, do người giữ bản ghi hiện tại trong APL thực hiện trong 24 ký tự.
Adám

Khi bạn có> = 3 $, có khả năng bạn có thể di chuyển nó đến liên kết trước đó và tham khảo lại Ç.
dùng202729

@ user202729 Ồ đúng rồi, cảm ơn.
HyperNeutrino

3

05AB1E , 27 25 byte

Cảm ơn Emigna đã lưu 2 byte!

Sử dụng tọa độ 1 chỉ mục.

Mã số:

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

Sử dụng mã hóa 05AB1E . Hãy thử trực tuyến!

Giải trình:

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

Điều này cho chúng ta mảng sau:

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

Đó là deltas của các động thái của hiệp sĩ.

            δ+             #   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

Bạn có thể sử dụng •eĆ•SÍü‚thay vì Ƶ‡4в2ô<D(«để lưu 2 byte.
Emigna

@Emigna Ahh, thật thông minh, cảm ơn!
Ad Nam

2

Python 3, 105 byte

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

Phải sử dụng lambda có tên cho đệ quy. Không chắc chắn nếu đó là không đủ điều kiện. Vượt qua ở các vị trí bắt đầu dưới dạng danh sách số vuông 0. 0 được tính là không di chuyển.


2

Java (OpenJDK 8) , 124 byte

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

Hãy thử trực tuyến!

Định dạng đầu vào / đầu ra

Đầu vào / đầu ra được biểu diễn dưới dạng các bit trong một long(64 bit): các bit set có nghĩa là một con ngựa có mặt, các bit unset có nghĩa là không có ngựa. Thí dụ:

// [[0, 0]]
0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000001L

Giải thích

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

Tín dụng

  • 19 byte được lưu nhờ có Nevay!
  • Sử dụng lại (X-x)²+(Y-y)²==5mẹo từ câu trả lời JavaScript của Arnauld
  • Thêm 1 byte được lưu nhờ vào Nevay trong thuật toán mới!
  • Thêm 7 byte được lưu nhờ vào Nevay một lần nữa bằng cách chuyển từ int[]64 bit long.

1
169 byte:(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 byte:(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

Cảm ơn bạn @Nevay! Thêm mã để loại bỏ dấu ngoặc đơn / khối luôn luôn tốt đẹp! ;-)
Olivier Grégoire

1
-7 byte bằng cách thay thế int[]bằng 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

Chúc mừng, tôi thậm chí không nghĩ về việc làm như vậy! Làm tốt lắm, @Nevay ;-)
Olivier Grégoire

2

Thạch , 29 28 byte

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

Hãy thử trực tuyến!

Số lượt là thông qua STDIN và hình vuông là một đối số.

Điều này ràng buộc giải pháp Jelly của HyperNeutrino, nhưng với một cách tiếp cận khác.

Bây giờ đánh bại @HyperNeutrino bằng 1 byte toàn bộ!

Bất kỳ đề xuất để loại bỏ một số byte được mong muốn!

Liên kết 1 (Bàn cờ)

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

Liên kết 2 (Di chuyển thế hệ)

“¦Ʋƈ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)

Liên kết 3 (kiểm tra vuông)

ÇƓ¡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

Husk , 18 byte

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

Sử dụng lập chỉ mục 1 hình vuông và các bước. Hãy thử trực tuyến!

Giải trình

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 byte

Đây là kết quả của việc chơi golf xuất sắc của Giuseppe đối với môn thể thao không quá golf ban đầu của tôi (xem bình luận bên dưới)

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

Hãy thử trực tuyến!

Đầu vào và đầu ra là 1 ... 64 dựa. Lấy một vectơ vị trí bằng cách sử dụng ký hiệu 1 ... 64. Ánh xạ tới ký hiệu 1: 576, đó là một bảng siêu được làm bằng chín bảng. Trong ký hiệu này, ở mỗi lần lặp, mỗi hiệp sĩ sẽ có thể di chuyển bằng +/- 22,26,47,49 Trả lại các vị trí trong tương lai trở lại trong ký hiệu 1 ... 64, ngoại trừ những vị trí rơi khỏi bảng trung tâm. Ví dụ TIO hiển thị kết quả bằng cách sử dụng ma trận 8x8.


Điều này dường như thất bại trong trường hợp thử nghiệm đầu tiên (nó trả về 4 tọa độ thay vì 2).
Zgarb

Cảm ơn bạn đã chỉ ra Zgarb, tôi nghĩ rằng tôi đã khắc phục vấn đề ngay bây giờ
NofP


hoặc 148 byte nếu bạn lấy nó trong [0...63]ký hiệu thay thế.
Giuseppe

1
134 byte , [1..64]cho đầu vào và đầu ra. +1, mặc dù, đây là một câu trả lời tuyệt vời.
Giuseppe
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.