นี่คือการวาดซ้ำหรือไม่


13

ปัญหา:

ในหมากรุกมีกฎที่รู้จักกันดีเกี่ยวกับการวาดโดยการทำซ้ำ หากตำแหน่งเดิมซ้ำ 3 ครั้ง (หรือมากกว่า) จากนั้นผู้เล่นที่ประสงค์จะทำการเคลื่อนที่ซึ่งจะทำให้การซ้ำเกิดขึ้นนี้สามารถอ้างสิทธิ์เสมอ

บางครั้งนี่เป็นงานง่ายสำหรับผู้ชี้ขาดที่จะมองเห็นหากการเคลื่อนไหวสองสามครั้งสุดท้ายเป็นเพียงผู้เล่นที่เคลื่อนที่ไปข้างหน้าและถอยหลัง บางครั้งมันก็เล็กน้อยเล็กน้อยเมื่อชิ้นส่วนเคลื่อนไหวอย่างมีนัยสำคัญระหว่างตำแหน่งที่ทำซ้ำ

ปัญหาในการท้าทายนี้คือการส่งออกค่าความจริงถ้าตำแหน่งที่อ้างสิทธิ์ถูกดึงโดยการทำซ้ำ (ได้รับการเห็น 3 ครั้งหรือมากกว่า) และค่าเท็จถ้าตำแหน่งที่อ้างสิทธิ์ไม่ได้ถูกวาดโดยการทำซ้ำให้รายการของการเคลื่อนไหวในสัญ ตามที่อธิบายไว้ด้านล่างหรือสัญกรณ์ใด ๆ ที่คุณเลือก (แต่คุณจะต้องแปลงกรณีทดสอบ)


ตำแหน่งคืออะไร?

ในสถานการณ์โลกแห่งความเป็นจริงตำแหน่งจะได้รับผลกระทบจากสิ่งต่าง ๆ เช่นว่าผู้เล่นสามารถปิดกั้นปราสาทได้หรือไม่ก็ตาม คุณไม่ควรพิจารณาสิ่งเหล่านี้ในการแก้ปัญหาของคุณ ในปัญหานี้ตำแหน่งถูกกำหนดโดยการกำหนดค่าของชิ้นส่วนบนกระดาน ดังนั้นเพื่อจุดประสงค์ของปัญหานี้จะเห็นสองตำแหน่งเหมือนกันถ้าแต่ละตารางในกระดานทั้งสองนั้นถูกครอบครองโดยชิ้นส่วนประเภทเดียวกันที่มีสีเดียวกัน นี่ไม่จำเป็นต้องเป็นชิ้นส่วนที่แน่นอนเช่นอัศวินสีขาวสามารถสลับสี่เหลี่ยมและหากชิ้นส่วนอื่น ๆ ทั้งหมดตรงตามเงื่อนไขนี้จะยังคงอยู่ในตำแหน่งเดียวกัน


สัญกรณ์ที่ถูกต้องมีลักษณะอย่างไร

แม้ว่าฉันจะอธิบายพิกัดสัญกรณ์ แต่คุณมีอิสระที่จะป้อนด้วยระบบสัญกรณ์ที่คุณเลือก โดยมีเงื่อนไขว่า:

  • แต่ละรายการในสัญกรณ์อธิบายใด ๆ หรือทั้งหมด: ชิ้นส่วน / ชิ้นส่วนที่เกี่ยวข้อง; ไม่ว่าจะเป็นการตรวจสอบรุกฆาตตรวจสอบอีกครั้งรุกฆาตหรือทางตันได้รับการจัดส่ง; ถ้าเกิดการจับภาพ ตำแหน่งเริ่มต้น ตำแหน่งสุดท้าย
  • คุณอาจไม่มีข้อมูลเกี่ยวกับการทำซ้ำในเอกสารของคุณ

ดังนั้นตราบใดที่เกณฑ์เหล่านี้ตรงตามที่ฉันยินดีที่จะยอมรับตราบใดที่คุณระบุไว้ในคำตอบของคุณระบบสัญกรณ์ของคุณ ซึ่งอาจเป็นเช่น 0 แถวที่จัดทำดัชนีสิ่งอันดับคอลัมน์หรือสิ่งอื่น ๆ ที่เหมาะสมสำหรับโปรแกรมของคุณ


สัญลักษณ์พิกัด

สัญกรณ์ประสานงานเป็นสัญกรณ์ที่อธิบายถึงการย้ายอย่างหมดจดเป็นระบบของพิกัด

การเคลื่อนย้ายถูกอธิบายเป็นพิกัดแรกเริ่มจากชุด{A1-H8}จากนั้นพิกัดปลายทางอีกครั้งจากชุดเดียวกัน ดังนั้นกลเม็ดของกษัตริย์ก็จะดูเหมือน (เป็นชุดของสตริง)

{"E2-E4","E7-E5","F2-F4"}

ฉันเชื่อว่ามันเป็นสัญลักษณ์ที่ดีที่สุดที่จะใช้สำหรับปัญหานี้เพราะมันไม่ได้เกลื่อนไปด้วยข้อมูลภายนอกเช่นว่าการตรวจสอบได้เกิดขึ้นหรือสิ่งที่ชนิดของการเคลื่อนย้ายชิ้นส่วนคือ ดังที่ได้กล่าวไว้ก่อนหน้าสัญกรณ์สามารถเลือกได้ดังนั้นคุณสามารถใช้สัญกรณ์อื่นเช่นสัญกรณ์พีชคณิตหรือคุณสามารถปรับเปลี่ยนสัญกรณ์นี้ (เช่นลบเครื่องหมายขีดคั่นหรือใช้เป็นรายการของสิ่งอันดับ)


กฎ:

  • คุณไม่ควรพิจารณาว่าตำแหน่งหรือการเคลื่อนไหวนั้นถูกต้องหรือไม่เฉพาะในกรณีที่ทำให้เกิดการซ้ำซ้อน
  • คุณสามารถสันนิษฐานได้ว่าการเลื่อนตำแหน่งและการจำนำจะไม่เกิดขึ้น
  • คุณควรใช้รายการสตริงเป็นอินพุตและเอาต์พุตค่าความจริงหรือเท็จที่สอดคล้องกับว่าการทำซ้ำที่สาม (หรือมากกว่า) เกิดขึ้นในการย้ายครั้งสุดท้าย
  • เกมเริ่มต้นที่ตำแหน่งเริ่มต้นมาตรฐานสำหรับหมากรุกเสมอ ตำแหน่งเริ่มต้นสามารถนับรวมการทำซ้ำ
  • การวาดโดยการทำซ้ำไม่เกิดขึ้นหากการเคลื่อนไหวครั้งสุดท้ายไม่เกิดขึ้นตำแหน่ง

กฎทั่วไป:

  • นี่คือดังนั้นคำตอบที่สั้นที่สุดในหน่วยไบต์ชนะ
    อย่าปล่อยให้ภาษารหัสกอล์ฟกีดกันคุณจากการโพสต์คำตอบด้วยภาษาที่ไม่ได้เข้ารหัส พยายามหาคำตอบสั้น ๆ ที่เป็นไปได้สำหรับภาษาโปรแกรม 'ใด ๆ '
  • กฎมาตรฐานใช้สำหรับคำตอบของคุณด้วยกฎ I / O ที่เป็นค่าเริ่มต้นดังนั้นคุณจึงได้รับอนุญาตให้ใช้ STDIN / STDOUT ฟังก์ชั่น / วิธีพร้อมพารามิเตอร์ที่เหมาะสมและประเภทผลตอบแทนโปรแกรมเต็มรูปแบบ การโทรของคุณ
  • ช่องโหว่เริ่มต้นเป็นสิ่งต้องห้าม
  • หากเป็นไปได้โปรดเพิ่มลิงก์พร้อมทดสอบรหัสของคุณ (เช่นTIO )
  • นอกจากนี้ขอแนะนำให้เพิ่มคำอธิบายสำหรับคำตอบของคุณ

กรณีทดสอบ

คุณควรคืนค่าความจริงสำหรับ:

{"B1-C3","B8-C6","C3-B1","C6-B8","B1-C3","B8-C6","C3-B1","C6-B8"} 
{"B1-C3","B8-C6","C3-B1","C6-B8","B1-C3","B8-C6","C3-B1","C6-B8","B1-C3","B8-C6","C3-B1","C6-B8"}
{"B1-C3","B8-C6","D2-D4","D7-D5","D1-D3","D8-D6","C3-B1","C6-B8","B1-C3","B8-C6","D3-D1","D6-D8","D1-D3","D8-D6"}
{"D2-D4","B8-C6","E2-E4","C6-D4","D1-E2","D4-E6","E2-F3","E6-D4","F3-D1","D4-C6","D1-E2","C6-D4","E1-D1","D4-C6","D1-E1","C6-D4"}
{"B1-C3","B8-C6","C3-B1","C6-B8","B1-C3","B8-C6","C3-B1","C6-B8","B1-C3","B8-C6","C3-B1","C6-B8","B1-C3"}

และค่าเท็จสำหรับ:

{}
{"E2-E4","E7-E5","F2-F4"}
{"B1-C3","B8-C6","C3-B1","C6-B8","B1-C3","B8-C6","C3-B1","C6-B8","F2-F4","F7-F5"}
{"E2-E4","E7-E5","G1-F3","B8-C6","F1-C4","G8-F6","F3-G5","D7-D5","E4-D5","F6-D5","G5-F7"}
{"D2-D4","B8-C6","E2-E4","C6-D4","D1-E2","D4-C6","E2-D1","C6-D4","D1-E2","D4-C6","E2-D1"}
{"B1-C3","B8-C6","C3-B5","C6-B4","B5-D4","B4-D5","D4-C6","D5-C3","C6-B8","C3-B1","B8-C6","B1-C3","C6-B8","C3-B1"}
{"E2-E4","E7-E5","D1-E2","E8-E7","E1-D1","D8-E8","E2-E1","E7-D8","E1-E2","E8-E7","E2-E1","E7-E8"}

เราสามารถนำข้อมูลเข้าพูดรายการของจำนวนสแควร์สเรียงตามลำดับแถวลำดับหลักกำจัดหมากรุกทั้งหมดได้หรือไม่? รายการคู่ของพิกัดเป็นอย่างไร
สรรพนามของฉันคือ monicareinstate

คุณจะไม่สามารถกำจัดหมากรุกได้อย่างสมบูรณ์เนื่องจากชิ้นส่วนและการจับชิ้นส่วนต่างก็มีความสำคัญ คุณสามารถกำหนดระบบพิกัดได้ตามต้องการ ฉันจะอธิบายในคำถามว่าคุณสมบัติของชุดอินพุตที่ถูกต้องจะมีอะไร
ข้อมูลหมดอายุ

1
@KevinCruijssen ฉันจะเพิ่มอย่างชัดเจนว่าสถานะเริ่มต้นนับ ฉันคิดว่าคุณเห็นว่าชิ้นส่วนสำคัญดังนั้นสีของชิ้นส่วน กรณีทดสอบสุดท้ายที่สองคือที่อัศวินดำและขาวสลับกัน ในช่วงสุดท้ายราชินีและราชาสลับกันสำหรับผู้เล่นทั้งสอง
ข้อมูลหมดอายุ

1
@ExpiredData คุณช่วยอธิบายได้ไหมว่าทำไมกรณีที่มีข้อผิดพลาดที่ 3 เป็นเท็จ หลังจากตำแหน่งสุดท้ายC6-B8เกิดขึ้นสามครั้ง
อดัม

2
อาจะต้องเป็นตำแหน่งสุดท้ายที่ปรากฏอย่างน้อยสองครั้งก่อน
Adám

คำตอบ:


9

APL (ส่วนขยายของ Dyalog) , 55 49 47 45 44 ไบต์SBCS

-4 ขอบคุณ ngn

โปรแกรมเต็มรูปแบบ พรอมต์สำหรับรายการที่กลับรายการของคู่พิกัดที่กลับรายการ:
 เช่น{"B1-C3","B8-C6"}คือ[[[8,2],[6,3]],[[1,2],[3,3]]]

2≤≢s∩{0,∘⊃@⍺⊃s,←⊂⍵}/⎕,⊂(⊖⍪-)¯4↑⍉6,⍪5,∘⌽⍥⍳s3

ลองออนไลน์! (รวมถึงฟังก์ชั่นยูทิลิตี้Coordsที่แปลรูปแบบของ OP)

ตั้งค่ารายการสถานะ:

s←3 กำหนดสามถึงs(สำหรับs tates)

เนื่องจาก 3 ไม่ใช่สถานะกระดานที่ถูกต้องมันจะไม่ส่งผลต่อจำนวนการทำซ้ำของเราและเราต้องการค่าการส่งผ่านของการมอบหมาย ...

สร้างตัวแทนกระดานหมากรุก:

5... ทิ้งว่าสำหรับผลของการใช้ฟังก์ชั่นที่ได้รับต่อไปนี้ระหว่าง 5 และ 3:
⍥⍳ ขยายการขัดแย้งทั้งสองของพวกเขาɩ ndices;
  [1,2,3,4,5]... [1,2,3]
,∘⌽ ด้านซ้ายตัดกับด้านหลังด้านขวา
  [1,2,3,4,5,3,2,1]นี่เป็นตัวแทนของเจ้าหน้าที่

 ทำให้เป็นตาราง
[[1],
[2],
[3],
[4],
[5],
[3],
[2],
[1]]

6, prepend (แต่ละแถว) หกตัวแทนเบี้ย;
[[6,1],
[6,2],
[6,3],
[6,4],
[6,5],
[6,3],
[6,2],
[6,1]]

 ไขว้;
[[6,6,6,6,6,6,6,6],
[1,2,3,4,5,3,2,1]]

¯4↑ รับค่าลบ (เช่นสุดท้าย) สี่ (แถว), padding ด้วยเลขศูนย์แทนสี่เหลี่ยมที่ว่างเปล่า
[[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[6,6,6,6,6,6,6,6],
[1,2,3,4,5,3,2,1]]

(... ) ใช้ฟังก์ชัน tacit ต่อไปนี้กับสิ่งนั้น:

- ลบล้าง (ซึ่งหมายถึงสีตรงข้าม);
  [[ 0, 0, 0, 0, 0, 0, 0, 0],
   [ 0, 0, 0, 0, 0, 0, 0, 0],
   [-6,-6,-6,-6,-6,-6,-6,-6],
   [-1,-2,-3,-4,-5,-3,-2,-1]]

  ⊖⍪ สแต็คอาร์กิวเมนต์พลิกด้านบนของที่ให้เราเต็มบอร์ด;
  [[ 1, 2, 3, 4, 5, 3, 2, 1],
   [ 6, 6, 6, 6, 6, 6, 6, 6],
   [ 0, 0, 0, 0, 0, 0, 0, 0],
   [ 0, 0, 0, 0, 0, 0, 0, 0],
   [ 0, 0, 0, 0, 0, 0, 0, 0],
   [ 0, 0, 0, 0, 0, 0, 0, 0],
   [-6,-6,-6,-6,-6,-6,-6,-6],
   [-1,-2,-3,-4,-5,-3,-2,-1]]

สร้างรายการการเคลื่อนไหวตามด้วยสถานะเริ่มต้น:

 ล้อมรอบนั้น (เพื่อถือว่าเป็นหน่วยเดียว)

⎕, พรอมต์สำหรับรายการการเคลื่อนไหวและเสริมให้เป็นสถานะเริ่มต้น

ย่อขนาด * โดยฟังก์ชั่นที่ผนวกสถานะปัจจุบันเข้ากับรายการและทำการย้าย:

{... }/ ลดโดยแลมบ์ดานิรนามดังต่อไปนี้:

 อาร์กิวเมนต์ที่ถูกต้อง (สถานะปัจจุบัน)

 ล้อมรอบเพื่อใช้เป็นหน่วย

s,← ในสถานที่ผนวกเข้ากับรายการของรัฐ

 เปิดเผยให้ใช้รัฐนั้น

 … @⍺ ที่องค์ประกอบที่มีพิกัดสองค่าที่อาร์กิวเมนต์ซ้ายแสดงแทน:
  0 a zero
  , ตาม
   ด้วย
   ค่าแรก
สิ่งนี้มีประสิทธิภาพ "ย้าย" ค่าที่พิกัดแรกไปยังพิกัดที่สองโดยทิ้งไว้ที่ศูนย์

ตรวจสอบว่าเรามีสถานะสุดท้ายสามสถานะขึ้นไปหรือไม่:

s∩ จุดตัดของทุกรัฐด้วยสุดท้าย ส่วนย่อยของรัฐที่เหมือนกัน

 นับพวกมันขึ้นมา

2≤ ตรวจสอบว่ามีสองคนหรือมากกว่านั้น (เช่นสามคนขึ้นไปรวมถึงสถานะสุดท้าย)


* APL เชื่อมโยงกันอย่างถูกต้องดังนั้นก่อนอื่นฟังก์ชันจะถูกเรียกด้วยสถานะเริ่มต้นเป็นอาร์กิวเมนต์ที่ถูกต้องและการย้ายเริ่มต้นเป็นอาร์กิวเมนต์ซ้ายแล้วผลลัพธ์ของมันคือสถานะใหม่กลายเป็นอาร์กิวเมนต์ขวาใหม่ด้วยการย้ายที่สองเป็นอาร์กิวเมนต์ซ้ายใหม่ ฯลฯ ผลลัพธ์สุดท้ายคือ


ฉันค่อนข้างมั่นใจว่าเรื่องนี้จะสั้นลงอย่างมากโดยใช้การสแกน\แทนการลด/
Adám

บันทึก 2 ไบต์กับน่าเกลียดสับนี้: ->⍳3⊣s←⍬ ⍳s←3มันใช้งานได้เพราะ3ไม่ใช่บอร์ดที่ถูกต้องดังนั้นมันจะไม่ส่งผลกระทบต่อการตรวจจับการซ้ำซ้อน
ก.ย.

@ngn Ugh ขอบคุณ เรากำลังเข้าใกล้วุ้น
อดัม

(0,⊃)@->0,∘⊃@
ngn

@ngn เรียบร้อยแล้ว ขอบคุณ
Adám

6

R , 180 177 144 ไบต์

function(M,`+`=rep,l=c(1:5,3:1,6+8,0+16)){z=rev(Reduce(function(x,y){x[y[2:1]]=x[y]*1:0;x},M,c(l,-rev(l)),,T));sum(sapply(z,identical,el(z)))>2}

ลองออนไลน์!

-3 ไบต์ขอบคุณ Giuseppe
-29 ไบต์ขอบคุณการใช้ Nick Kennedy Reduceและ-rev(l)
-4 ไบต์โดยการย้อนกลับz

ใช้เป็นอินพุตเวกเตอร์ของจำนวนเต็มระหว่าง 1 ถึง 64 แสดงถึงช่องสี่เหลี่ยม TIO มีฟังก์ชั่นที่จะแปลงเป็นรูปแบบนั้น ชิ้นส่วนต่าง ๆ จะถูกเก็บเป็นจำนวนเต็มตั้งแต่ 1 ถึง 6 และระหว่าง -1 ถึง -6

คำอธิบาย:

function(M,                                # M is the vector of moves 
         `+` = rep,
         l = c(1:5, 3:1, 6 + 8, 0 + 16)) { # initial position of white pieces
  z = rev(Reduce(function(x, y) {
    x[y[2:1]] = x[y] * 1:0                 # a piece moves from y[1] to y[2]; y[1] becomes 0
    x
  }, M, c(l, -rev(l)), , T))
  sum(sapply(z, identical, el(z))) > 2    # find number of past positions identical to the last position
}

1
ฉันได้ใส่รุ่นปรับปรุงของคุณที่ [ bit.ly/2OHPexp] มันโอเค TIO แต่ลิงค์ยาวเกินไปสำหรับความคิดเห็น รหัสของคุณได้แรงบันดาลใจจากคุณ แต่ใช้สะสมReduceที่หลักของมัน มันคือ 148 ไบต์
Nick Kennedy

@NickKennedy ขอบคุณ! จริง ๆ แล้วฉันกำลังจะใช้จำนวนเต็มลบสำหรับชิ้นส่วนสีดำ ฉันดีใจที่คุณทำมันก่อน ฉันชอบสิ่งที่คุณทำกับลด: ฉันต้องการเรียนรู้เพิ่มเติมเกี่ยวกับเรื่องนี้อย่างชัดเจน
Robin Ryder

@NickKennedy ฉันได้เพิ่มรุ่นของคุณอีก 4 ไบต์โดยการย้อนกลับ z
Robin Ryder

3

เจลลี่ , 41 37 ไบต์

Ø0;6x8;“Ġ²F’D¤UN;ƊW;µị@⁹Ṫ¤¦0⁹¦$\ċṪ$>1

ลองออนไลน์!

ลิงก์ monadic ที่รับอินพุตเป็นรายการคู่ของการย้ายแถวหลักที่มีการจัดทำดัชนี 1 คู่[from, to]และส่งคืน 1 สำหรับการดึงและ 0 ไม่ใช่

หมายเหตุรหัสส่วนท้ายของ TIO แปลการเคลื่อนไหวตามที่ OP กำหนดให้เป็นรูปแบบตัวเลข แต่ตามการสนทนาด้านล่างคำถามรูปแบบตัวเลขจะเป็นอินพุตที่ถูกต้อง

คำอธิบาย

Ø0                                    | 0,0
  ;6                                  | concatenate to 6 (pawn)
    x8                                | repeat each 8 times (two blank rows and 1 row of pawns)
      ;“Ġ²F’D¤                        | concatenate to 1,2,3,4,5,3,2,1
              UN;Ɗ                    | concatenate a negated flipped version to this one
                  W;                  | wrap as a list and concatenate the input list to the board
                    µ                 | start a new monadic chain
                              $\      | reduce using the two links below
                     ị@⁹Ṫ¤¦           | replace the item pointed to by the second coordinate by the value of the one at the first
                           0⁹¦        | replace the item at first coordinate with zero
                                ċṪ$   | finally count the items equal to the final one (not including it)
                                   >1 | and check of >1

3

JavaScript (Node.js) ,  121  111 ไบต์

[sq0, sq1][0..63]a8=0b8=1h1=63

ส่งคืนค่าบูลีน

a=>[a,...a].map(([x,y])=>r=b[b[b[y]=b[x],x]=0,b]=-~b[b],b=[...'89ABCA981111111'+10n**32n+0x7e5196ee74377])&&r>2

ลองออนไลน์!

อย่างไร?

ชิ้น

ค่าที่ใช้ในการระบุชิ้นส่วนไม่สำคัญตราบใดที่มีค่าที่ไม่ซ้ำกันต่อประเภทชิ้น

เราใช้:

  • 0สำหรับสี่เหลี่ยมที่ว่างเปล่า
  • 1 / 8 / 9 / / B / Cสำหรับ♟ / ♜ / ♞ / ♝ / ♛ / ♚
  • 2 / 3 / 4 / 5 / 6 / 7สำหรับ♙ / ♖ / ♘ / ♗ / ♕ / ♔

คณะกรรมการและตำแหน่งเริ่มต้น

b

  • '89ABCA981111111' →ชิ้นส่วนหลัก 8 ชิ้นสีดำตามด้วยโรงรับจำนำสีดำ 7 ชิ้นแรก
  • 10n**32nh710
  • 0x7e5196ee74377→ชิ้นส่วนสีขาวทั้งหมด (ใช้กับ2222222234567543ทศนิยม

ซึ่งผลลัพธ์ใน:

    a b c d e f g h
  +----------------
8 | 8 9 A B C A 9 8
7 | 1 1 1 1 1 1 1 1
6 | 0 0 0 0 0 0 0 0
5 | 0 0 0 0 0 0 0 0
4 | 0 0 0 0 0 0 0 0
3 | 0 0 0 0 0 0 0 0
2 | 2 2 2 2 2 2 2 2
1 | 3 4 5 6 7 5 4 3

การติดตามตำแหน่ง

bb

นี่คือเหตุผลที่เราทำ:

b[b] = -~b[b]

แสดงความคิดเห็น

a =>                    // a[] = input
  [ a,                  // dummy entry to mark the initial position as encountered once
    ...a                // append the actual data
  ].map(([x, y]) =>     // for each pair of squares [x, y] in this array:
    r =                 //   store the last result in r
    b[                  //   update b[b]:
      b[                //     update b[x]:
        b[y] = b[x],    //       set b[y] to b[x]
        x               //       set b[x] ...
      ] = 0,            //     ... to 0
      b                 //     set b[b] ...
    ] = -~b[b],         //   ... to b[b] + 1 (or 1 if b[b] is undefined)
    b = [...(…)]        //   initialize b[] (see above)
  )                     // end of map()
  && r > 2              // return true if the last result is greater than 2

ฉันยังไม่ได้เขียนกรณีทดสอบ แต่ยังใช้งานได้ไหมถ้าสลับสีเดียวกันทั้งสองชิ้น (เช่นการทำซ้ำที่มีการสลับอัศวินม้าขาวสองตัว)? ฉันจะเขียนกรณีทดสอบเมื่อฉันมีโอกาส
ข้อมูลหมดอายุ

ใช่ฉันหมายความว่าฉันจะอัปเดตเมื่อฉันสามารถ
ข้อมูลหมดอายุ

1
@ExpiredData ตอนนี้ควรทำงานได้ตามที่คาดไว้
Arnauld

3

Java 10, 336 330 287 285 282 276 ไบต์

m->{var V=new java.util.HashMap();int i=64,A[]=new int[i];var t="";for(;i-->0;)t+=A[i]=(i%56<8?i%8*35%41%10%8+2:9>>i/16&1)*(i/32*2-1);V.put(t,1);for(var a:m){for(t="",A[a[1]]=A[a[0]],A[a[0]]=0,i=64;i-->0;)t+=A[i];V.compute(t,(k,v)->v!=null?(int)v+1:1);}return(int)V.get(t)>2;}

-11 ไบต์ขอบคุณที่@Arnauldโดยการเปลี่ยนไปi%56<8?"ABCDECBA".charAt(i%56%7):i%48<16?1:0i%56<8?i%8*35%41%10%8+2:9>>i/16&1

a1=0,b1=1,...,h8=63{"E2-E4",...[[12,28],...

ลองออนไลน์

คำอธิบาย:

m->{                   // Method with 3D character array parameter and boolean return-type
  var V=new java.util.HashMap();
                       //  Create a Map to store the occurrences of the board-states
  int i=64,            //  Index integer, starting at 64
      A[]=new int[i];  //  Create the 8 by 8 board
  var t="";            //  Temp-String, starting empty
  for(;i-->0;)         //  Loop `i` in the range (64,0]:
    t+=                //    Append the string `t` with:
      A[i]=            //     Fill the `i`'th cell with:
        i%56<8?        //      If it's either the first or eighth row:
         i%8*35%41%10%8+2
                       //       Fill it with 2,7,3,5,9,3,7,2 based on index `i`
        :9>>i/16&1)    //      Else if it's either the second or seventh row:
                       //       Fill it with 1
                       //      Else (the third, fourth, fifth, or sixth rows):
                       //       Fill it with 0
        *(i/32*2-1);   //      Then multiply it by -1 or 1 depending on whether `i`
                       //      is below 32 or not
  V.put(t,1);          //  Then set string `t` in the map to 1 for the initial state
  for(var a:m){        //  Loop over each of the input's integer-pairs:
    for(t="",          //   Make the String empty again
        A[a[1]]=       //   Set the to-cell of the current integer-pair of the input to:
          A[a[0]],     //    The value in the from-cell of the same integer-pair
        A[a[0]]=0,     //   And then empty this from-cell
        i=65;i-->0;)   //   Inner loop `i` in the range (64,0]:
          t+=A[i];     //    Append the `i`'th value to the String `t`
    V.compute(t,(k,v)->v!=null?(int)v+1:1);}
                       //   Increase the value in the map for String `t` as key by 1
  return(int)V.get(t)  //  Return whether the value in the map for the last String `t`
          >2;}         //  is at least 3

ค่าของชิ้นส่วนหลังจากเติมพวกเขาด้วยA[i]=(i%56<8?i%8*35%41%10%8+2:9>>i/16&1)*(i/32*2-1)คือ:

     a  b  c  d  e  f  g  h
  +------------------------
1 | -2 -7 -3 -5 -9 -3 -7 -2
2 | -1 -1 -1 -1 -1 -1 -1 -1
3 |  0  0  0  0  0  0  0  0
4 |  0  0  0  0  0  0  0  0
5 |  0  0  0  0  0  0  0  0
6 |  0  0  0  0  0  0  0  0
7 |  1  1  1  1  1  1  1  1
8 |  2  7  3  5  9  3  7  2

ลองออนไลน์


มีการต่อสู้ในขณะที่มีวิธีหลีกเลี่ยงการใช้ t ไม่มีโครงสร้างที่คุณสามารถใช้ในการจัดเก็บสถานะซึ่งจะทำอะไรเช่น java.util.Arrays.deepHashCode หรือไม่? ถ้าเป็นเช่นนั้นโหลดได้หลายไบต์
ข้อมูลหมดอายุ

นอกจากนี้ฉันสงสัยว่านี่ถูกต้องทางเทคนิคหรือไม่ตามการใช้ hashmap อาจมีการชนกันของแฮชสำหรับกระดานหมากรุกเนื่องจากการกำหนดค่าที่เป็นไปได้นั้นมีขนาดใหญ่หรือไม่ ฉันจะไม่ยกตัวอย่างให้คุณอย่างนั้น!
ข้อมูลหมดอายุ

1
@ExpiredData มีแน่นอนเป็นjava.util.Arrays.deepHashCode(A)แต่เห็นได้ชัดว่าบางส่วนของแฮชยังคงเดิมอย่างใด (เช่นกรณีทดสอบที่ผ่านมามี-447346111=3ในแผนที่ .. ) ถ้าผมเปรียบเทียบแผนที่ส่งผลของคำตอบปัจจุบันของฉันและแผนที่ที่เกิดขึ้นโดยใช้ deepHashCode(A)นอกจากนี้มันจะยาวกว่า 3 ไบต์แทนที่จะสั้นกว่าเนื่องจากฉันต้องใช้deepHashCode(A)สองครั้ง (สำหรับสถานะเริ่มต้นเช่นกัน)
Kevin Cruijssen

1
แต่ตัวโกงสีดำตัวแรกนั้นแตกต่างจากตัวโกงสีดำตัวที่สอง two positions are seen to be the same if each square on both boards is occupied by the same type of piece of the same colour
ศูนย์รวมแห่งความไม่รู้

1
ไม่ผ่านการทดสอบอย่างเต็มรูปแบบใน Java แต่การแสดงออกi%8*35%41%10%8+2ควรจะเป็นไปได้แทนการ"ABCDECBA".charAt(i%8)บันทึก 6 ไบต์ [ 2, 7, 3, 5, 9, 3, 7, 2 ]มันสร้างรูปแบบ
Arnauld

2

ถ่าน , 62 ไบต์

≔↨²³⁴⁵⁶⁴³²χηF⁴⁸⊞η÷⁻⁴⁰ι³²F…η⁸⊞η±ιFθ«⊞υ⮌η§≔η⊟ι§η§ι⁰§≔η⊟ι⁰»›№υ⮌η¹

ลองออนไลน์! การเชื่อมโยงคือการใช้รหัสเวอร์ชันอย่างละเอียด รับอินพุตเป็นอาร์เรย์ของคู่ของตัวเลขที่มีกำลังสองเป็นเลขA1,, B1... H8(0- ดัชนี) ดังนั้นเช่นกรณีทดสอบครั้งแรกจะแสดงเป็น[[[1, 18], [57, 42], [18, 1], [42, 57], [1, 18], [57, 42], [18, 1], [42, 57]]]และส่งออก a -หากตำแหน่งเป็นการวาดโดยการทำซ้ำ โปรแกรมการแปลง ทั้งหมดในอย่างเดียว. คำอธิบาย:

≔↨²³⁴⁵⁶⁴³²χη

แยกตัวเลข23456432ออกเป็นตัวเลขแต่ละตัว สิ่งเหล่านี้แสดงถึงชิ้นส่วนสีขาว

F⁴⁸⊞η÷⁻⁴⁰ι³²

เพิ่มในเบี้ยและแถวที่ว่างเปล่า เบี้ยสีขาวมีค่าและสีดำเบี้ย1-1

F…η⁸⊞η±ι

ผนวกสำเนาสีขาวเมื่อตะกี้ซึ่งเป็นตัวแทนของชิ้นส่วนสีดำ

Fθ«

วนรอบการเคลื่อนไหว

⊞υ⮌η

บันทึกสำเนาของบอร์ด (การกลับด้านเป็นวิธีที่ง่ายที่สุดในการคัดลอกกระดาน)

§≔η⊟ι§η§ι⁰

อัปเดตปลายทางด้วยชิ้นส่วนต้นทาง

§≔η⊟ι⁰

ลบชิ้นส่วนที่มา

»›№υ⮌η¹

ตรวจสอบว่าตำแหน่งปัจจุบันถูกเห็นมากกว่าหนึ่งครั้งก่อน


2

C # (Visual C # Interactive Compiler) , 204 ไบต์

n=>{var j=new List<char[]>();var d=("ABCDECBATTTTTTTT"+new string('Z',32)+7777777712345321).ToArray();foreach(var(a,b)in n){j.Add(d.ToArray());d[b]=d[a];d[a]='Z';}return j.Count(r=>r.SequenceEqual(d))>1;}

รับอินพุตเป็นรายการของ tuples ของจำนวนเต็มโดยที่เลขจำนวนเต็มแรกคือตำแหน่งที่จะย้ายจากและที่สองคือตำแหน่งที่จะย้ายไป 0 หมายถึง A1, 1 คือ A2 และ 63 คือ H8

ลองออนไลน์!

n=>{
  var j=new List<char[]>();    //Initialize a list to save states of a board
  var d=("ABCDECBATTTTTTTT" +  //White pieces
  new string('Z',32) +         //Empty spaces
  7777777712345321)            //Black pieces
  .ToArray(); //Initialize the chessboard
  foreach(var(a,b)in n){       //Foreach (source square, destination square) in the input
    j.Add(d.ToArray());        //  Add the current board to the list
    d[b]=d[a];                 //  Set the destination square to the source square's value
    d[a]='Z';                  //  And set the souce square to empty
  }
  return j.Count(         //Return that the amount...
    r=>r.SequenceEqual(d) //  of past positions that are equal to the current position...
  )>1;                    //is at least two
}

0

Java (JDK) , 246 245 244 ไบต์

import java.util.*;n->{var j=new ArrayList<char[]>();var d=("ABCDECBATTTTTTTT"+"".repeat(32)+7777777712345321l).toCharArray();for(var k:n){j.add(d.clone());d[k[1]]=d[k[0]];d[k[0]]=1;}return j.stream().filter(x->Arrays.equals(d,x)).count()>1;}

ลองออนไลน์!

import java.util.*;                   //Import the java.util package

n->{                                  //Function taking in int[][], 
                                      //where each int[] is a a pair of numbers
  var j = new ArrayList<char[]>();    //List to save each position of the chessboard
  var d =                             //The chessboard's starting position
    ("ABCDECBATTTTTTTT" +             //  All the white pieces
    "&#1".repeat(32) +                //  Plus the empty squares
    7777777712345321l)                //  And the black pieces
  .toCharArray();                     //Split to array of chars
  for(var k:n){                       //Foreach [sourceSquare, destinationSquare] in input
    j.add(d.clone());                 //  Add the current position to the list
    d[ k[1] ] = d[ k[0] ];            //  Set the destination square's value
                                      //  to the source squares
    d[ k[0] ] = 1;                    //  And clear the source square 
}                                     //End foreach
return j.stream()                     //Convert list of states to stream
  .filter(x ->                        //Filter each position by
    Arrays.equals(d,x)                //  if the position equals the final position 
  ).count() > 1;                      //And return if there are at least two
                                      //positions that are left
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.