อัศวินอยู่ที่ไหนในการเคลื่อนที่ N ครั้ง?


21

นี่คือหลุมที่ 3 จากฤดูใบไม้ร่วงทัวร์นาเมนต์ของ APL CodeGolf ฉันเป็นผู้เขียนปัญหาดั้งเดิมที่นั่นและอนุญาตให้โพสต์ใหม่ได้ที่นี่


ได้รับ:

  1. จำนวนรอบ (โปรดระบุหากไม่มีการเคลื่อนไหวใดเป็น 0 มิฉะนั้นเราจะถือว่าเป็น 1) และ

  2. รายการของตำแหน่งเริ่มต้นอย่างน้อยหนึ่งรายการ (ในรูปแบบใด ๆ เช่น 0 หรือ 1 ดัชนีที่มีการจัดทำดัชนีหรือตัวเลข / ตัวอักษร 64 ตัวต่อเนื่องหรือ A1-H8 - สถานะใด) บนกระดานหมากรุกขนาด 8 คูณ 8

ย้อนกลับ (ตามลำดับ) รายการของตำแหน่งที่ไม่ซ้ำกัน (ในรูปแบบเดียวกับอินพุต) ที่อัศวิน (s) สามารถอยู่ที่หลังจำนวนรอบที่กำหนด

  • อัศวินแต่ละคนจะต้องเคลื่อนที่ในทุกเทิร์น แต่คุณไม่ต้องกังวลกับอัศวินหลายคนที่อยู่ในจตุรัสเดียวกัน

  • อัศวินสามารถย้ายไปยังตำแหน่งที่มีเครื่องหมาย 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 แทน [rank, file] ได้หรือไม่?
เดฟ

@Dave ทำไมไม่? เพียงแค่สอดคล้องกับ I / O
อดัม

8
ฉันสาบานว่าฉันอ่าน HNQ นี้ว่า "อัศวินอยู่ที่ไหนในการเคลื่อนไหวของ Ni"
Sidney

3
Pun alert: สัญกรณ์สำหรับอัศวินคือ N.
Joshua

เราสามารถใช้การจัดทำดัชนีแบบอิงตามจำนวนขั้นตอนได้หรือไม่ เช่น[[1,1]], 2 -> [[2,3],[3,2]]
Zgarb

คำตอบ:


11

ภาษา Wolfram (Mathematica)ขนาด 45 ไบต์

เนื่องจากโซลูชันอื่นไม่ถูกต้อง (ดูความคิดเห็นของ Martin ด้านล่าง) ดังนั้นฉันจึงตัดสินใจโพสต์โซลูชันของฉัน:

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

ลองออนไลน์!

สัญกรณ์สุดยอดมัด ...

รับอินพุต 2 ตัวอันแรกคือรายการหมายเลขที่อยู่ในช่วง[1,64]อธิบายตำแหน่งเริ่มต้นของอัศวินส่วนที่สองคือจำนวนก้าว

วิธีนี้ขึ้นอยู่กับความสะดวกสบายสูงสุดของฟังก์ชั่น Mathematica builtin:

  • AdjacencyListอาจใช้รายการจุดยอดทางด้านขวาของมันและกลับรายการจุดยอดที่อยู่ติดกับใด ๆ ของเหล่านั้นลบรายการที่ซ้ำกันและเรียงลำดับแล้ว
  • KnightTourGraphเป็น builtin ไม่แปลกใจ
  • Nestใช้เวลาการขัดแย้งในการสั่งซื้อNest[f, expr, n]ซึ่งเราสามารถแดงกว่าด้านขวาเป็น##Nest[f, ##]
  • และในที่สุด Mathematica ก็แยกวิเคราะห์a~b~c~d~eเป็น(a~b~c)~d~eดังนั้นจึงไม่จำเป็นต้องใช้วงเล็บเหลี่ยม โดยไม่ต้องสัญกรณ์มัดและแผ่มันจะเป็น##Nest[AdjacencyList[KnightTourGraph[8, 8], #] &, #, #2]&

1
ฉันไม่คิดว่าจะมีอะไรผิดปกติกับการแก้ปัญหาที่มีอยู่
อดัม

1
สิ่งนี้ใช้ได้กับหลายตำแหน่งเริ่มต้นหรือไม่
อดัม

! ที่น่าตื่นตาตื่นใจ ตอนนี้ฉันต้องหาวิธีที่ ti อ่านเรื่องนี้ ...
เดฟ

นี่อาจเป็น 17 ไบต์ในภาษา Mthmca golfing สมมุติฐาน
Michael Stern

7

JavaScript (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

เนื่องจาก1และ4เป็นสี่เหลี่ยมจัตุรัสที่สมบูรณ์แบบเพียงอย่างเดียวที่ให้5เมื่อ XOR จะอยู่ด้วยกันเรามีการเคลื่อนที่ของอัศวินที่ถูกต้องหาก:

(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`.*¶	

ลองออนไลน์! ใช้อินพุตเป็นบอร์ด 8x8 :ที่มีอัศวินที่มีเครื่องหมายด้วยNs พร้อมตัวเลขสำหรับจำนวนรอบในบรรทัดถัดไป (มันไม่มีเหตุผลที่จะมีมากกว่า 9 รอบ แต่ถ้าคุณยืนยันว่าฉันสามารถรองรับได้เป็นพิเศษ ไบต์) โปรดทราบว่าการส่งออกมีพื้นที่สีขาวเพิ่มเติม แก้ไข: บันทึก 45 ไบต์ขอบคุณ @MartinEnder คำอธิบาย: ขั้นตอนแรกแปลงจำนวนการเปลี่ยนเป็นเอกภาพ แต่ใช้อักขระแท็บเพื่อไม่ให้ถูกจับคู่โดยบังเอิญในขณะที่ขั้นตอนที่สองเพิ่มช่องว่างทางด้านขวาของกระดานเพื่อหยุดการ regexes ข้าม ขอบ. ขั้นตอนที่สามแทนที่Nและ:s ที่มีการย้ายอัศวินออกไปจากNที่มีnในขณะที่ขั้นตอนที่สี่ลบใด ๆ ที่เหลือNของการเปลี่ยนแปลงns ถึงNs และลบ 1 จากการนับการย้าย สิ่งนี้จะทำซ้ำจนกว่าการนับการย้ายจะเป็นศูนย์


นี่คือที่น่าประทับใจที่สุด ไม่ใช่เครื่องมือที่เหมาะสมสำหรับงาน!
อดัม

4

เยลลี่ 29 ไบต์

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

ลองออนไลน์!

0- ดัชนีพิกัด เกือบจะแน่ใจว่านี่เป็นสิ่งที่ไม่ดี

-1 ไบต์ขอบคุณ user202729

คำอธิบาย

+þ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 อัน?
อดัม

1
@ Adámทำให้การกรองง่ายขึ้น: P
HyperNeutrino

2
ฉันคาดหวังว่า Jelly จะสามารถทำสิ่งนี้ได้ใน 15 ไบต์เนื่องจากเจ้าของสถิติปัจจุบันใน APL ทำได้ใน 24 ตัวอักษร
อดัม

เมื่อคุณมี> = $ 3 Çก็มีโอกาสที่คุณสามารถย้ายไปยังลิงค์ก่อนหน้าและอ้างกลับมาพร้อมกับ
user202729

@ user202729 โอ้ใช่จริงขอบคุณ
HyperNeutrino

3

05AB1E , 27 25 ไบต์

ขอบคุณEmignaสำหรับการบันทึก 2 ไบต์!

ใช้พิกัด 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

Python 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

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

เครดิต

  • บันทึกไปแล้ว 19 ไบต์ด้วย Nevay!
  • นำ(X-x)²+(Y-y)²==5เคล็ดลับจากคำตอบ JavaScriptของ Arnauld กลับมาใช้ใหม่
  • มีการบันทึกอีก 1 ไบต์ด้วย Nevay ในอัลกอริทึมใหม่!
  • อีก 7 ไบต์บันทึกขอบคุณที่ Nevay อีกครั้งโดยเปลี่ยนจาก64int[] บิตlong

1
169 bytes:(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[]ด้วย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 และ squares เป็นอาร์กิวเมนต์

ความสัมพันธ์นี้เป็นโซลูชันเยลลี่ของ @ HyperNeutrino แต่ด้วยแนวทางที่แตกต่าง

ตอนนี้เต้น @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

Husk , 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 134 ไบต์

นี่เป็นผลจากการเล่นกอล์ฟที่ยอดเยี่ยมของ Giuseppe ในช่วงเริ่มต้นที่ไม่มากเกินไป (ดูความคิดเห็นด้านล่าง)

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 ซึ่งเป็นซุปเปอร์บอร์ดที่ทำจากเก้าบอร์ด ในสัญกรณ์นี้ที่การวนซ้ำแต่ละครั้งอัศวินแต่ละคนควรสามารถเคลื่อนที่ได้โดย +/- 22,26,47,49 คืนตำแหน่งในอนาคตกลับคืนใน 1 ... 64 สัญกรณ์ยกเว้นที่ตกจากกระดานกลาง ตัวอย่าง TIO แสดงผลลัพธ์โดยใช้เมทริกซ์ 8x8


สิ่งนี้ดูเหมือนว่าจะล้มเหลวในกรณีทดสอบครั้งแรก (มันส่งกลับ 4 พิกัดแทน 2)
Zgarb

ขอบคุณสำหรับการชี้ให้เห็น Zgarb ฉันคิดว่าฉันแก้ไขปัญหาได้แล้วตอนนี้
NofP


หรือ148 ไบต์หากคุณใช้[0...63]สัญลักษณ์แทน
Giuseppe

1
134 ไบต์ , [1..64]สำหรับอินพุตและเอาต์พุต +1 อย่างไรก็ตามนี่เป็นคำตอบที่ยอดเยี่ยม
Giuseppe
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.