Di mana ksatria berada di N bergerak?

21

Ini adalah Hole-3 dari The Autumn Tournament dari APL CodeGolf . Saya adalah penulis asli masalah di sana, dan dengan demikian diizinkan memposting ulang di sini.


Diberikan:

  1. sejumlah belokan (sebutkan jika tidak ada gerakan adalah 0, kalau tidak kita akan menganggap itu disebut 1) dan

  2. daftar satu atau lebih posisi awal (dalam bentuk apa pun, misalnya 0 atau 1 koordinat yang diindeks atau 64 angka / karakter berurutan atau A1 – H8 - sebutkan mana), pada papan catur 8-oleh-8,

mengembalikan (dalam urutan apa pun) daftar posisi unik (dalam format yang sama dengan input) yang dapat diberikan oleh knight setelah jumlah putaran yang diberikan.

  • Setiap ksatria harus bergerak dengan setiap belokan, tetapi Anda tidak perlu khawatir tentang beberapa ksatria yang menempati kotak yang sama.

  • Seorang kesatria hanya dapat bergerak ke posisi yang ditandai dengan X relatif terhadap posisi saat ini, ditandai dengan ♞:
    di mana seorang kesatria bisa bergerak

Contoh (koordinat 1-diindeks)

1pindah dari [[1,1]]: [[2,3],[3,2]]

2pindah dari [[1,1]]: [[1,1],[1,3],[1,5],[2,4],[3,1],[3,5],[4,2],[4,4],[5,1],[5,3]]

1pindah dari [[1,1],[5,7]]: [[2,3],[3,2],[3,6],[3,8],[4,5],[6,5],[7,6],[7,8]]

2pindah dari [[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]]

0pindah dari [[3,4]]: [[3,4]]

Adm
sumber
Bisakah ruang catur dimasukkan dan dikeluarkan dengan penomoran 0-63 bukan [peringkat, file]?
Dave
@Dave Tentu, mengapa tidak? Konsisten dengan I / O.
Adám
8
Aku bersumpah aku membaca HNQ ini sebagai "Di mana ksatria berada di Ni bergerak"
Sidney
3
Peringatan Pun: notasi untuk ksatria adalah N.
Joshua
Bisakah kita menggunakan pengindeksan berbasis 1 pada jumlah langkah? Misalnya[[1,1]], 2 -> [[2,3],[3,2]]
Zgarb

Jawaban:

11

Bahasa Wolfram (Mathematica) , 45 byte

Karena solusi lain salah (lihat komentar Martin di bawah), jadi saya memutuskan untuk mengirim solusi saya:

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

Cobalah online!

Notasi pemasangan tertinggi ...

Mengambil 2 input, yang pertama adalah daftar angka dalam kisaran yang [1,64]menggambarkan posisi awal ksatria, yang kedua adalah jumlah langkah.

Solusi ini bergantung pada kenyamanan ekstrem fungsi Mathematica builtin:

  • AdjacencyListmungkin mengambil daftar simpul di sisi kanannya, dan mengembalikan daftar simpul yang berdekatan dengan salah satu dari mereka, sudah dihapus duplikat dan diurutkan .
  • KnightTourGraphadalah builtin. Tidak mengejutkan.
  • Nestmengambil argumen secara berurutan Nest[f, expr, n], yang dapat kita percikkan di ##sisi kanannya sebagai Nest[f, ##].
  • Dan akhirnya, Mathematica parse a~b~c~d~eas (a~b~c)~d~e, jadi tidak perlu tanda kurung siku. Tanpa notasi infix dan ratakan ##, itu akan menjadi Nest[AdjacencyList[KnightTourGraph[8, 8], #] &, #, #2]&.
pengguna202729
sumber
1
Saya tidak berpikir ada yang salah dengan mengungguli solusi yang ada.
Adám
1
Apakah ini berfungsi dengan beberapa posisi awal?
Adám
Luar biasa! Sekarang saya perlu mencari tahu bagaimana saya membaca ini ...
Dave
Ini mungkin 17 byte dalam bahasa golf Mthmca hipotetis.
Michael Stern
7

JavaScript (ES7), 99 byte

Format input / output: indeks kuadrat dalam [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

Uji kasus

Cuplikan ini mencakup dua fungsi pembantu untuk menerjemahkan dari dan ke format yang disediakan oleh OP.

Bagaimana?

Sebuah perpindahan dari (x, y) ke (X, Y) adalah langkah ksatria yang valid jika kita memiliki salah satu dari:

  • | xX | = 1 dan | yY | = 2 , atau
  • | xX | = 2 dan | yY | = 1

Dengan mengkuadrat alih-alih menggunakan nilai absolut, ini dapat dinyatakan sebagai:

  • (xX) ² = 1 dan (yY) ² = 4 , atau
  • (xX) ² = 4 dan (yY) ² = 1

Karena 1 dan 4 adalah satu-satunya kotak sempurna yang memberikan 5 ketika XOR bersama, kami memiliki langkah ksatria yang valid jika:

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

Kami menerapkan rumus ini untuk setiap kotak p = 8y + x di papan tulis dan setiap kotak ksatria P = 8Y + X untuk menyimpulkan kotak target ksatria baru yang mungkin, dan mengulangi proses ini secara n kali.

Arnauld
sumber
5

Oktaf, 69 byte

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

Demo online!

Input / output adalah konfigurasi board saat start / end sebagai matriks biner 8 * 8.

Penjelasan:

Untuk nlangkah - langkah, ulangi pelebaran morfologis papan dengan topeng berikut:

01010
10001
00100
10001
01010
rahnema1
sumber
5

Retina , 147 102 byte

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

Cobalah online! Mengambil input sebagai papan 8x8 :s dengan ksatria bertanda Ns, dengan digit untuk jumlah belokan pada baris berikutnya (tidak masuk akal memiliki lebih dari 9 putaran, tetapi jika Anda bersikeras saya dapat mendukungnya untuk tambahan byte). Perhatikan bahwa output berisi ruang putih tambahan. Sunting: Disimpan 45 byte berkat @MartinEnder. Penjelasan: Tahap pertama mengubah jumlah belokan ke unary, tetapi menggunakan karakter tab, sehingga mereka tidak dapat dicocokkan kemudian secara tidak sengaja, sedangkan tahap kedua menambahkan beberapa ruang di sebelah kanan papan untuk menghentikan regex dari membungkus tepi. Tahap ketiga menggantikan semua Ns dan :s yang merupakan langkah ksatria menjauh dari Ndengan nsementara tahap keempat menghapus sisa Ns, mengubahns ke Ns, dan kurangi 1 dari jumlah langkah. Ini berulang sampai jumlah langkah nol.

Neil
sumber
Ini yang paling mengesankan. Jelas bukan alat yang tepat untuk pekerjaan itu!
Adám
4

Jelly , 29 byte

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

Cobalah online!

Koordinat 0-diindeks. Hampir pasti ini suboptimal.

-1 byte terima kasih kepada pengguna202729

Penjelasan

+þ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)
HyperNeutrino
sumber
1
0-diindeks Jelly?
Adám
1
@ Adám Membuat penyaringan lebih mudah: P
HyperNeutrino
2
Saya berharap Jelly dapat melakukan ini di bawah 15 byte, karena pemegang rekor saat ini di APL melakukannya dalam 24 karakter.
Adám
Ketika Anda memiliki> = 3 $, kemungkinan Anda dapat memindahkannya ke tautan sebelumnya dan merujuk kembali dengan Ç.
user202729
@ user202729 Oh ya benar, terima kasih.
HyperNeutrino
3

05AB1E , 27 25 byte

Terima kasih kepada Emigna untuk menghemat 2 byte!

Menggunakan koordinat 1-diindeks.

Kode:

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

Menggunakan penyandian 05AB1E . Cobalah online!

Penjelasan:

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

Ini memberi kita array berikut:

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

Yang merupakan delta pergerakan ksatria.

            δ+             #   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
Adnan
sumber
Anda dapat menggunakan •eĆ•SÍü‚alih-alih Ƶ‡4в2ô<D(«menyimpan 2 byte.
Emigna
@Emigna Ahh, itu pintar, terima kasih!
Adnan
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

Harus menggunakan lambda bernama untuk rekursi. Tidak yakin apakah itu mendiskualifikasi. Lulus di posisi awal sebagai daftar nomor kotak terindeks 0. 0 dianggap tidak bergerak.

mypetlion
sumber
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;}

Cobalah online!

Format Input / Output

Input / output direpresentasikan sebagai bit dalam long(64 bit): bit yang diset berarti kuda hadir, bit yang tidak disetel berarti tidak ada kuda. Contoh:

// [[0, 0]]
0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000001L

Penjelasan

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

Kredit

  • 19 byte disimpan berkat Nevay!
  • Menggunakan kembali (X-x)²+(Y-y)²==5trik dari jawaban JavaScript Arnauld
  • 1 byte lebih tersimpan berkat Nevay dalam algoritme baru!
  • 7 byte lagi disimpan berkat Nevay lagi dengan beralih dari int[]64-bit long.
Olivier Grégoire
sumber
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
Terima kasih @Nay! Menambahkan kode untuk menghapus tanda kurung / blok selalu bagus! ;-)
Olivier Grégoire
1
-7 byte dengan menggantinya int[]dengan 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
Ceria, aku bahkan tidak berpikir untuk melakukan itu! Kerja bagus, @Nevay ;-)
Olivier Grégoire
2

Jelly , 29 28 byte

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

Cobalah online!

Jumlah belokan adalah melalui STDIN, dan kuadrat adalah argumen.

Ini mengikat solusi Jelly @ HyperNeutrino, tetapi dengan pendekatan yang berbeda.

Sekarang kalahkan @HyperNeutrino sebanyak 1 byte penuh!

Setiap saran untuk menjatuhkan beberapa byte diinginkan!

Tautan 1 (Papan catur)

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

Tautan 2 (Pindahkan generasi)

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

Tautan 3 (pengecekan kotak)

ÇƓ¡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
Zacharý
sumber
1

Sekam , 18 byte

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

Menggunakan pengindeksan kuadrat dan langkah 1 berbasis. Cobalah online!

Penjelasan

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.
Zgarb
sumber
1

R , 145 183 134 byte

Ini adalah hasil dari permainan golf Giuseppe yang bagus untuk algo awal saya yang tidak terlalu golf (lihat komentar di bawah)

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

Cobalah online!

Input dan output berbasis 1 ... 64. Mengambil vektor posisi menggunakan notasi 1 ... 64. Memetakannya ke notasi 1: 576, yaitu papan super yang terbuat dari sembilan papan. Dalam notasi ini, pada setiap iterasi, masing-masing ksatria harus dapat bergerak dengan +/- 22,26,47,49 Mengembalikan posisi masa depan kembali dalam notasi 1 ... 64, tidak termasuk yang jatuh dari papan pusat. Contoh TIO menampilkan hasilnya menggunakan matriks 8x8.

NofP
sumber
Ini tampaknya gagal pada test case pertama (mengembalikan 4 koordinat bukan 2).
Zgarb
Terima kasih telah menunjukkannya pada Zgarb, saya pikir saya telah memperbaiki masalah ini sekarang
NofP
154 byte
Giuseppe
atau 148 byte jika Anda mengambilnya sebagai [0...63]notasi.
Giuseppe
1
134 byte , [1..64]untuk input dan output. +1, meskipun demikian, ini adalah jawaban yang sangat bagus.
Giuseppe