Şövalye N hamlede nerede olabilir?


21

Bu APL CodeGolf'un Sonbahar Turnuvasından Delik 3 . Ben ordaki problemin asıl yazarıyım ve bu yüzden tekrar buraya gönderdim.


Verilen:

  1. bir kaç tur (lütfen hiçbir hareketin 0 olmadığını belirtin, aksi takdirde 1 olarak adlandırılacağını varsayalım) ve

  2. 8'e 8'lik bir satranç tahtasında bir veya daha fazla başlangıç ​​pozisyonu listesi (herhangi bir biçimde, örneğin, 0 veya 1 indekslenmiş koordinat veya 64 ardışık sayı / karakter veya A1 --- H8 - durum hangisi),

(herhangi bir sırayla) şövalye (ler) in verilen tur sayısından sonra olabileceği benzersiz pozisyonların (girişle aynı formatta) listesini döndürün.

  • Her şövalye her turda hareket etmelidir, ancak aynı meydanda bulunan birden fazla şövalye hakkında endişelenmenize gerek yoktur.

  • Bir şövalye, yalnızca ♞ ile işaretlenmiş mevcut konumuna göre X ile işaretlenmiş konumlara hareket edebilir:
    bir şövalyenin hareket edebileceği yer

Örnekler (1 indeksli koordinatlar)

1taşın [[1,1]]: [[2,3],[3,2]]

2taşınır [[1,1]]: [[1,1],[1,3],[1,5],[2,4],[3,1],[3,5],[4,2],[4,4],[5,1],[5,3]]

1taşın [[1,1],[5,7]]: [[2,3],[3,2],[3,6],[3,8],[4,5],[6,5],[7,6],[7,8]]

2taşınır [[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]]

0taşınır [[3,4]]: [[3,4]]


Satranç sıraları [rank, dosya] yerine 0-63 numaralandırılarak girilebilir ve çıkarılabilir mi?
Dave,

@Dave Emin, neden olmasın? Sadece G / Ç ile tutarlı olun.
Adám

8
Yemin ederim bu HNQ’yu “Şövalye Ni’de hareket ediyor” olarak okudum
Sidney

3
Pun uyarısı: şövalye için gösterim N'dir.
Joshua

Adım sayısına göre 1 tabanlı indeksleme kullanabilir miyiz? Eg[[1,1]], 2 -> [[2,3],[3,2]]
Zgarb

Yanıtlar:


11

Wolfram Dili (Mathematica) , 45 bayt

Diğer çözüm yanlış olduğu için (aşağıdaki Martin yorumuna bakın), bu yüzden çözümümü göndermeye karar verdim:

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

Çevrimiçi deneyin!

Nihai infix notasyonu ...

2 giriş alır, ilki [1,64]şövalyenin başlangıç ​​pozisyonlarını tanımlayan aralıktaki numaraların bir listesidir , ikincisi ise adımların sayısıdır.

Bu çözüm, Mathematica yerleşik işlevlerinin aşırı kolaylığına dayanır:

  • AdjacencyListsağ tarafındaki köşelerin bir listesini alabilir ve bunlardan herhangi birine bitişik, halihazırda yinelenen çoğaltılmış ve sıralanmış bir köşelerin listesini döndürür .
  • KnightTourGraphbir yerleşiktir. Sürpriz değil
  • Nestsırayla Nest[f, expr, n], ##onun sağ tarafını da çevirebileceğimiz argümanları alır Nest[f, ##].
  • Ve nihayet, Mathematica ayrıştırmak a~b~c~d~eolarak (a~b~c)~d~ehiçbir köşeli ayraç gereklidir, böylece. Ekleme notasyonu ve düzleştirme olmadan ##, olur Nest[AdjacencyList[KnightTourGraph[8, 8], #] &, #, #2]&.

1
Mevcut bir çözümü aşmakta yanlış bir şey olduğunu sanmıyorum.
Adem

1
Bu çoklu başlangıç ​​pozisyonları ile çalışır mı?
Adem

Şaşırtıcı! Şimdi bunu nasıl okuduğumu bulmam gerek ...
Dave

Bu muhtemelen varsayımsal Mthmca golf dilinde 17 byte olacaktır.
Michael Stern

7

JavaScript (ES7), 99 bayt

Giriş / çıkış formatı: [0 ... 63] ' deki indeksleri kareler .

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

Test durumları

Bu kod parçası, OP tarafından sağlanan formata ve formattan çeviri yapmak için iki yardımcı fonksiyon içerir.

Nasıl?

Gelen bir hareket (x, y) ile (X, Y) biz ya varsa geçerli Knight bir hareket:

  • | xX | = 1 ve | yY | = 2 veya
  • | xX | = 2 ve | yY | = 1

Mutlak değerler kullanmak yerine kareler çizildiğinde, bu şu şekilde ifade edilebilir:

  • (xX) ² = 1 ve (yY) ² = 4 veya
  • (xX) ² = 4 ve (yY) ² = 1

Çünkü 1 ve 4 vermek sadece mükemmel kareler 5 XOR birlikte, geçerli bir şövalye hareket halinde olduğunda:

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

Bu formülü tahtadaki her p = 8y + x karesine ve her yeni şövalye karesi P = 8Y + X'e yeni olası şövalye hedef karelerini bulmak için uygularız ve bu işlemi n tekrarlı olarak tekrar ederiz .


5

Octave, 69 bayt

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

Çevrimiçi Demo!

Giriş / çıkış, kartın başlangıçtaki / sondaki ikili 8 * 8 matris olarak yapılandırılmasıdır.

Açıklama:

İçin nadımlar aşağıdaki maske ile kurulu morfolojik genişlemesini tekrarlamak:

01010
10001
00100
10001
01010

5

Retina , 147 102 bayt

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

Çevrimiçi deneyin! :S ile işaretlenmiş şövalyeler Nile bir sonraki satırdaki dönüş sayısı için bir rakam ile 8x8'lik bir s kartı girişini alır (9 turdan fazla olması anlamsızdır, ancak ısrar edersen fazladan destekleyebilirim. bayt). Çıktının ek beyaz boşluk içerdiğini unutmayın. Düzenleme: @ Martininder sayesinde 45 bayt kaydedildi. Açıklama: İlk aşama, dönüş sayısını birliğe çevirir ancak sekme karakterleri kullanır, böylece daha sonra kazayla eşleşmezler, ikinci aşama ise regex'lerin sarılmasını önlemek için tahtanın sağına bazı boşluklar ekler kenar. Üçüncü aşama , bir şövalyenin bir süre sonra uzaklaştığı tüm Nlerin yerini alır , dördüncü aşama kalanları siler ,:NnNns'den Ns'ye, ve hareket sayısından 1 'i çıkarır. Bu, hareket sayısı sıfır olana kadar tekrar eder.


Bu en etkileyici. Kesinlikle iş için doğru araç değil!
Adám

4

Jöle , 29 bayt

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

Çevrimiçi deneyin!

0 indeksli koordinatlar. Neredeyse kesin bu suboptimal.

User202729 sayesinde -1 bayt

açıklama

+þ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 indekslenmiş Jelly?
Adám

1
P: Adam filtreleme kolay yapar @
HyperNeutrino

2
Jelly'in 15 baytın altında bunu yapabilmesini bekliyorum, çünkü APL'deki mevcut kayıt sahibi 24 karakterde yapıyor.
Adem

> = 3 $ olduğunda, önceki bağlantıya taşıyabilir ve tekrar başvurabilirsiniz Ç.
user202729

@ user202729 Ah evet, doğru.
HyperNeutrino 18:17

3

05AB1E , 27 25 bayt

2 bayt kaydettiğiniz için Emigna'ya teşekkürler !

1 indeksli koordinatları kullanır.

Kod:

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

05AB1E kodlamasını kullanır . Çevrimiçi deneyin!

Açıklama:

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

Bu bize şu diziyi verir:

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

Şövalyenin hareketlerinin deltaları.

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

2 bayt kaydetmek •eĆ•SÍü‚yerine kullanabilirsiniz Ƶ‡4в2ô<D(«.
Emigna

@Emigna Ahh, bu zekice, teşekkürler!
Adnan

2

Python 3, 105 bayt

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

Özyineleme için adlandırılmış bir lambda kullanmanız gerekir. Diskalifiye edici olduğundan emin değilim. Başlangıç ​​pozisyonlarında 0 indeksli kare numarası listesi olarak geçin. 0, hareket yok olarak sayılır.


2

Java (OpenJDK 8) , 124 bayt

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

Çevrimiçi deneyin!

Giriş / Çıkış formatı

Girdi / çıktı long(64 bit) cinsinden bitler olarak gösterilir: set bitleri bir atın var olduğu anlamına gelir, belirsiz bitler ise at olmadığı anlamına gelir. Örnek:

// [[0, 0]]
0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000001L

açıklamalar

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

Kredi

  • Nevay sayesinde 19 bayt kurtarıldı!
  • Arnauld'un JavaScript cevabındaki(X-x)²+(Y-y)²==5 numara tekrar kullanıldı
  • Nevay sayesinde yeni algoritmada 1 bayt daha kaydedildi!
  • Nevay sayesinde int[]64-bit'e geçiş yaparak 7 bayt daha kaydedildi long.

1
169 bayt:(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 bayt:(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'a teşekkür ederim! Parantez / blokları kaldırmak için kod eklemek her zaman iyidir! ;-)
Olivier Grégoire

1
-7 değiştirerek bayt int[]ile 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

Şerefe, böyle yapmayı düşünmedim bile! Güzel iş, @ Nevay ;-)
Olivier Grégoire

2

Jöle , 29 28 bayt

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

Çevrimiçi deneyin!

Sıra sayısı STDIN üzerindendir ve kareler bir argümandır.

Bu, @ HyperNeutrino'nun Jelly çözümünü bağlar, ancak farklı bir yaklaşımla.

Şimdi @HyperNeutrino 1 byte yeniliyor!

Bazı baytları kapatmak için herhangi bir öneriniz aranıyor!

Bağlantı 1 (Satranç tahtası)

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

Bağlantı 2 (Hareketi oluştur)

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

Bağlantı 3 (kare kontrol)

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

Kabuğu , 18 bayt

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

1-temelli karelerin ve adımların indekslenmesini kullanır. Çevrimiçi deneyin!

açıklama

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 bayt

Bu Giuseppe'nin ilk golf sahası olmayan algomun mükemmel golf oynamanın sonucudur (aşağıdaki yoruma bakın)

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

Çevrimiçi deneyin!

Giriş ve çıkış 1 ... 64'tür. 1 ... 64 gösterimini kullanarak bir pozisyon vektörü alır. Dokuz panodan oluşan bir süper tahta olan 1: 576 notasyonuna eşler. Bu gösterimde, her yinelemede, her şövalye +/- 22,26,47,49 oranında hareket edebilmelidir. Merkezden düşenler hariç 1 ... 64 gösterimde gelecekteki pozisyonları geri getirin. TIO örneği, 8x8'lik bir matris kullanarak sonucu görüntüler.


Bu ilk testte başarısız görünüyor (2 yerine 4 koordinat döndürüyor).
Zgarb

Gösterdiğin için teşekkür ederim Zgarb, sanırım sorunu şimdi düzelttim
NofP


veya bunun yerine gösterimde alırsanız 148 byte [0...63]
Giuseppe

1
134 bayt , [1..64]giriş ve çıkış için. +1, yine de bu mükemmel bir cevap.
Giuseppe
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.