รหัสปริศนารหัส Slidey!


12

เป็นที่รู้จักมากที่สุดปริศนาเลื่อนเป็นปริศนาสิบห้า มันมีตาราง 4 โดย 4, 15 กระเบื้องและพื้นที่ว่างหนึ่งตาราง กระเบื้องสามารถย้ายไปยังพื้นที่ว่างได้เท่านั้นและจะต้องสอดคล้องกับตารางเสมอ

ลองกำหนดตัวต่อแบบเลื่อนโดยทั่วไปเป็นWสองมิติกว้างด้วยตารางสูงH ( W , Hทั้งจำนวนเต็มบวก) ที่มีจำนวนของกระเบื้องที่ไม่มีเครื่องหมายเหมือนกันจำนวนหนึ่ง(ระหว่าง 0 ถึงW × Hของพวกเขา) ที่จัดเรียงในตาราง ไม่ว่าจะด้วยวิธีใดก็ตาม (โดยไม่ทับซ้อนกัน) ด้วยพื้นที่ตารางว่างเปล่าเติมส่วนที่เหลือของพื้นที่

ตัวอย่างเช่นถ้าWและHเป็น 3 และไทล์เป็นTและพื้นที่ว่างเป็นEหนึ่งในการจัดเรียงปริศนาเข้าข้างได้มากที่สุดคือ

TTT
TET
EET

สำหรับปริศนาเหล่านี้มี 4 ย้ายเป็นไปได้ทุกอย่างซุกขึ้น , ซุกทุกอย่างลงทุกอย่างซุกซ้ายหรือซุกทุกอย่างที่เหมาะสม 'การผลัก' ไปในทิศทางใดทิศทางหนึ่งทำให้ไพ่ทั้งหมดเดินทางไปในทิศทางนั้นไกลที่สุดเท่าที่จะเป็นไปได้จนกว่าพวกเขาจะชนกระเบื้องหรือขอบตาราง บางครั้งการผลักจะไม่เปลี่ยนเค้าโครงของกริด

หากกริดตัวอย่างถูกผลักไปทางขวาผลลัพธ์จะเป็น

TTT
ETT
EET

ผลักไปทางซ้ายผลคือ

TTT
TTE
TEE

ลดผลลัพธ์ลงไปคือ

EET
TET
TTT

(สังเกตว่าทั้งคู่เคลื่อนไหวไปทางซ้ายสุดT)

การเลื่อนขึ้นไม่ได้เปลี่ยนเค้าโครงตารางในกรณีนี้

โปรดทราบว่าเนื่องจากแผ่นกระเบื้องแยกไม่ออกปริศนาเหล่านี้จึงไม่มีสถานะ 'ที่แก้ไขแล้ว' นอกจากนี้โปรดทราบว่าตัวต่ออาจเริ่มจากเลย์เอาต์ที่เป็นไปไม่ได้ที่จะกลับไปเมื่อมีการผลัก (เช่นไทล์แผ่นเดียวที่อยู่กลางตาราง 3 คูณ 3)

ท้าทาย

การใช้ASCII ที่พิมพ์ได้เท่านั้นเขียนโค้ดสี่เหลี่ยมสองบล็อกทั้งMตัวกว้างและNตัวสูง (สำหรับจำนวนเต็มบวกM , N ) โค้ดบล็อกหนึ่งบล็อกจะแสดงถึงตัวต่อของตัวต่อแบบเลื่อนส่วนโค้ดบล็อกอีกอันจะแทนพื้นที่กริดว่าง

การจัดเรียงโค้ดบล็อกทั้งสองนี้ไว้ในตารางWโดยHจะสร้างตัวต่อแบบเลื่อนรหัสซึ่งสามารถบันทึกเป็นไฟล์ข้อความและเรียกใช้เป็นโปรแกรมปกติ เมื่อเรียกใช้โปรแกรมประเภทนี้ควรแจ้งผู้ใช้ผ่าน stdin เป็นตัวเลขตั้งแต่ 1 ถึง 4 1 ได้ถึง 2 ลง 3 ซ้าย 4 ขวา เมื่อผู้ใช้พิมพ์หมายเลขและจำนวนที่ป้อนโปรแกรมจะคำนวณวิธีการเรียงไทล์ซอร์สโค้ดในทิศทางนั้นและบันทึกเลย์เอาต์ปริศนาใหม่ในไฟล์ (ไม่ว่าจะเป็นไฟล์ใหม่หรือไฟล์เดียวกัน) จากนั้นจะสิ้นสุดลง

กระบวนการนี้สามารถทำซ้ำได้อย่างไม่มีกำหนดกับไฟล์รหัสตัวต่อใหม่ที่สร้างขึ้นหลังจากการผลักแต่ละครั้ง

ตัวอย่าง

สมมติว่าบล็อกรหัสกระเบื้องของฉันมีลักษณะเช่นนี้

//   my
// tile

และบล็อกรหัสพื้นที่กริดของฉันว่างเปล่าหน้าตาแบบนี้

//empty
//space

( M = 7, N = 2 ซึ่งแน่นอนว่าไม่ใช่รหัสจริง)

การจัดเรียงตัวต่อแบบเลื่อนที่ถูกต้องของบล็อกทั้งสองนี้ควรสร้างโปรแกรมในภาษาที่ฉันใช้ซึ่งสามารถเรียกใช้เพื่อให้ผู้ใช้ดันไปในทิศทางใดทิศทางหนึ่ง

การแทนรหัสของกริดตัวอย่างคือ:

//   my//   my//   my
// tile// tile// tile
//   my//empty//   my
// tile//space// tile
//empty//empty//   my
//space//space// tile

ดังนั้นให้เรียกใช้และกด 2 (ลงล่าง) จากนั้น Enter จะเขียนไฟล์นี้ไปยังไฟล์อื่น (หรือไฟล์เดียวกัน):

//empty//empty//   my
//space//space// tile
//   my//empty//   my
// tile//space// tile
//   my//   my//   my
// tile// tile// tile

ไฟล์นั้นจะสามารถเรียกใช้และผลักดันในลักษณะเดียวกัน

หมายเหตุ

  • การแทนรหัสใด ๆ ของตัวต่อสไลด์WโดยHควรจะสามารถรันได้และสามารถที่จะดันตัวเองได้อย่างเหมาะสม ซึ่งรวมถึงขนาดกริดทั้งหมดตั้งแต่ 1 ถึง 1 ถึงบางส่วนที่เหมาะสม (2 16โดย 2 16หรือมากกว่า)

  • โปรแกรมอาจอ่านซอร์สโค้ดของมันเอง ไม่มีข้อ จำกัด ตามควิน ความคิดเห็นของการเรียงลำดับใด ๆ ก็ดี

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

  • คุณอาจสมมติว่าอินพุตถูกต้องเสมอ (1, 2, 3 หรือ 4)

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

  • หากภาษาของคุณไม่รองรับ stdin ให้ใช้วิธีการป้อนข้อมูลที่ใกล้เคียงที่สุด

  • คุณสามารถกำหนดให้บรรทัดใหม่อยู่ท้ายไฟล์ปริศนารหัสของคุณ (หรือต้องการให้มันไม่อยู่ที่นั่น)

  • วิธีที่คุณตั้งชื่อไฟล์ใหม่ไม่สำคัญ f.txtหรือเพียงแค่fเป็นเรื่องปกติ

  • บล็อคโค้ดสองชุดอาจไม่เหมือนกัน

เกณฑ์การให้คะแนน

เป้าหมายคือการทำสิ่งนี้ด้วยขนาดรหัสที่เล็กที่สุด (ซึ่งเป็นสาเหตุที่ทำให้มีการติดแท็กโค้ดกอล์ฟ การส่งที่มีพื้นที่บล็อกรหัสน้อยที่สุด ( M × N ) เป็นผู้ชนะ ไทเกอร์เบรกเกอร์จะไปสู่คำตอบที่ได้รับการโหวตสูงสุด

ที่เกี่ยวข้อง: รหัสที่ใช้ Game of Life ด้วยตัวเอง


ดังนั้นโปรแกรมจำเป็นต้องทำงานเมื่อมีพื้นที่ว่างเท่านั้นและไม่มีบล็อกย่อย (และในทางกลับกัน)
grc

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

ฉันสามารถระบุชื่อของไฟล์ต้นฉบับได้หรือไม่?
feersum

@feersum เช่นคุณสามารถสันนิษฐานได้ว่ามันอยู่เสมอf.txt? ใช่.
งานอดิเรกของ Calvin

บล็อคโค้ดไม่ได้จะเป็น 1 บรรทัดเสมอไปหรือ บล็อคโค้ดหลายบรรทัดดูเหมือนจะซับซ้อนสำหรับฉันมากและภาษาอังกฤษแบบ 2 มิติอาจไม่สนับสนุนการเขียนไฟล์
กำหนด

คำตอบ:


5

TECO , 153

บล็อกว่างเปล่า:

0T@^Ux#EBx#27@:^Ux##MxA1^QUq^T%d/51%w"G153UsZ/QqUlQq/153Un|Qq%s/153UlZ/QqUn'Qd&1UhQl<.UpQn<Qh-\"F%c'TRQs:C>QpJQn<D-%c"L%c1-Qh\|Qh\'RQs:C>Qw"GC|153%pJ'>EX

บล็อกกระเบื้อง:

1T@^Ux#EBx#27@:^Ux##MxA1^QUq^T%d/51%w"G153UsZ/QqUlQq/153Un|Qq%s/153UlZ/QqUn'Qd&1UhQl<.UpQn<Qh-\"F%c'TRQs:C>QpJQn<D-%c"L%c1-Qh\|Qh\'RQs:C>Qw"GC|153%pJ'>EX

xโปรแกรมที่แก้ไขตัวเองในสถานที่ที่ต้องถูกบันทึกไว้ในไฟล์ชื่อ tecoc mung x.มันสามารถทำงานผ่านคำสั่ง จุดนั้นสำคัญ โดยไม่ได้ TECO x.tecพยายามที่จะหาไฟล์ที่ชื่อว่า บรรทัดใหม่ต่อท้ายจะต้องนำเสนอ

ข้อ จำกัด ASCII ที่พิมพ์ได้นั้นเป็นความเจ็บปวดเล็กน้อยสำหรับเรื่องนี้เนื่องจากภาษาใช้อักขระที่ไม่สามารถพิมพ์ได้จำนวนมาก ส่วนใหญ่พวกเขาสามารถถูกแทนที่ด้วยลำดับสองไบต์เริ่มต้นด้วยคาเร็ต แต่ "Escape" (ASCII 27) เป็นตัวละครตัวหนึ่งที่ 'หนีไม่พ้น' เพื่อให้ได้มันฉันต้องใส่ค่า ASCII ลงในสตริงและ ดำเนินการมัน ดังนั้น 4-byte จึงEBx<Esc>ระเบิดออก@^Ux#EBx#27@:^UX##Mxมา

สิ่งนี้สามารถลดลงอย่างมากโดยเฉพาะอย่างยิ่งโดยการแยกโปรแกรมออกเป็นสองส่วนเก็บไว้เป็นสตริงและทำงานเฉพาะเมื่อทั้งสองมีอยู่

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