วิธีแสดง Cube ของ Rubik ในโครงสร้างข้อมูล


58

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

สิ่งที่ต้องพิจารณา:

  • ลูกบาศก์สามารถมีขนาดใดก็ได้
  • มันเป็นลูกบาศก์ของรูบิคดังนั้นชั้นจึงสามารถหมุนได้

2
การบ้าน? หรือปัญหาในโลกแห่งความเป็นจริง ...
sdg

4
คุณอาจสนใจซอร์สโค้ดของCube Solver ของรูบิคนั้น
mouviciel

22
ฉันค่อนข้างแน่ใจว่าจำนวนด้านของลูกบาศก์ควรเป็น 6
Simon Bergot

3
ฉันอยากรู้อยากเห็นแบบจำลองของลูกบาศก์ของ Rubik แบนดังนั้นฉันสามารถเห็นทุกด้านพร้อมกัน อืมฉันอยากจะเขียนตอนนี้ มันอาจเป็นรูปร่างของ T หรือแม้กระทั่งปูกระเบื้องไม่รู้จบถ้าเป็นไปได้ (ฉันไม่ได้คิดหลังผ่าน)
Lee Kowalkowski

6
ผมรู้สึกว่าอยากจะพูดกับเอริคอีแวนส์ (คำพูดอาจจะไม่ถูกต้อง 100% ในขณะที่มันจะถูกอ้างถึงจากหน่วยความจำ) "รุ่นที่มีค่าที่ถูกต้องหรือไม่ถูกต้องพวกเขาเป็นเพียงมากหรือน้อยมีประโยชน์."
พีท

คำตอบ:


37

มีอะไรผิดปกติกับอาร์เรย์เก่าธรรมดาขนาด[6X][X]? คุณไม่จำเป็นต้องรู้เกี่ยวกับด้านมินิก้อนเพราะคุณไม่เห็นพวกเขา; ไม่ได้เป็นส่วนหนึ่งของสถานะคิวบ์ ซ่อนสองวิธีที่น่าเกลียดที่อยู่เบื้องหลังอินเตอร์เฟซที่ดูดีและใช้งานง่ายทดสอบหน่วยถึงความตายและ voila คุณทำเสร็จแล้ว!


31
แม้แต่ลูกบาศก์ของรูบิคตัวจริงก็ไม่มีลูกบาศก์ขนาดเล็กภายใน
jk

8
สิ่งนี้จะทำงานได้ แต่อัลกอริทึมของคุณอาจซับซ้อนเกินกว่าที่จะรองรับโครงสร้างข้อมูลที่เรียบง่าย
maple_shaft

6
As long as you know how the six surfaces are "threaded" together ซึ่งเป็นสิ่งที่โครงสร้างข้อมูลที่แข็งแกร่งจะให้คุณ ฉันคิดว่าเรากำลังโต้เถียงในสิ่งเดียวกัน ด้านอาเรย์และด้านที่เป็นอาเรย์ของบล็อกอย่างไรก็ตามมีคุณสมบัติที่น่าสนใจมากมายเกี่ยวกับด้านข้างและบล็อกที่ช่วยให้คิดว่า "การทำเกลียว" ไม่ชอบคำนั้นเพราะมันอาจสับสนกับมัลติเธรด )
maple_shaft

7
@maple_shaft "ซึ่งเป็นสิ่งที่โครงสร้างข้อมูลที่แข็งแกร่งมากขึ้นจะให้คุณ" ฉันไม่ทราบเกี่ยวกับสิ่งนั้น: โครงสร้างข้อมูลที่มี "โครงสร้าง" มากกว่านั้นจะทำให้เกิดความซับซ้อนเพิ่มเติมที่เกี่ยวข้องกับการตั้งค่าการบำรุงรักษาและการเข้าถึงแต่ละส่วนของโครงสร้างนั้น เป็นการยากที่จะบอกว่าอะไรจะซับซ้อนกว่านี้ - การใช้การเลื่อนที่น่าเกลียดในอาร์เรย์ธรรมดาที่มีบางมุมรวมถึงการ "นั่งฟรี" ในการเข้าถึงแต่ละเซลล์หรือโครงสร้างที่มีการเปลี่ยนแปลงที่ค่อนข้างซับซ้อนน้อยกว่าและอ่านค่อนข้างซับซ้อนกว่า
dasblinkenlight

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

39

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

ฉันอาจจะสร้างโครงสร้างข้อมูลแยกต่างหากเพื่อจับภาพลักษณะเฉพาะของแต่ละบล็อกในคิวบ์

มี 3 ประเภทของบล็อกที่แตกต่างกันในก้อน:

  1. มุมบล็อก - มันมีใบหน้าสามสีและสามชิ้นที่อยู่ติดกันซึ่งมันจะแบ่งปันด้านข้างได้ตลอดเวลา

  2. Edge Block - มันมีใบหน้าสองสีและมีชิ้นส่วนที่อยู่ติดกัน 4 ชิ้นที่จะแบ่งปันด้านข้างได้ตลอดเวลา ในบล็อก 3x3 มันมี 2 ชิ้นกลางและ 2 มุมเสมอ

  3. บล็อกกลาง - ในลูกบาศก์ 3x3 ชิ้นส่วนนี้ไม่สามารถเคลื่อนย้ายได้ แต่สามารถหมุนได้ มันจะมีบล็อคขอบ 4 อันติดกันเสมอ ในคิวบ์ที่มีขนาดใหญ่จะมีบล็อกกลางหลายอันที่สามารถแชร์กับบล็อกกลางอื่นหรือขอบชิ้น บล็อกกึ่งกลางจะไม่ติดกับบล็อกมุม

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

คิวบ์ใบหน้าทุกอันจะถูกนำเสนอเป็นใบหน้าที่ไม่ซ้ำ

ด้วยโครงสร้างข้อมูลเหล่านี้จะเป็นการง่ายที่จะเขียนอัลกอริธึมที่ดำเนินการเปลี่ยนแปลงการหมุนในแต่ละหน้าย้ายบล็อกที่เหมาะสมเข้าและออกจากรายการที่เหมาะสม

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


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

@Mel มันเป็นไปได้ที่จะทำอย่างใดอย่างหนึ่ง แต่หลังจากพูดคุยกับ dasblinkenlight จริง ๆ แล้วฉันคิดว่าวิธีการของเขาจะซับซ้อนน้อยกว่า ฉันหวังว่าคำตอบของเขาจะได้คะแนนมากกว่าของฉัน ฉันไม่ได้ดีกับอัลกอริทึมและมีประสิทธิภาพมากที่สุดฉันแค่ชอบ rubiks cubes และรวบรวมพวกมัน (มากกว่า 40 ชนิดที่แตกต่างจากทั่วทุกมุมโลก)
maple_shaft

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

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

@Ziv True แต่คำถามที่ถามเกี่ยวกับโครงสร้างข้อมูลและไม่จำเป็นต้องเกี่ยวกับอัลกอริทึม
maple_shaft

13

เมื่อฉันคิดถึงปัญหานี้ฉันคิดว่าลูกบาศก์แบบคงที่โดยมีสีที่เคลื่อนที่ผ่านในรูปแบบที่เป็นที่รู้จัก ดังนั้น....

วัตถุ Cube ประกอบด้วยวัตถุ 6 ด้านที่ยังคงอยู่ในดัชนีคงที่ 0-5 แต่ละด้านมีวัตถุ 9 ตำแหน่งที่ยังคงมีการจัดทำดัชนีไว้ 0-8 แต่ละตำแหน่งมีสี

สำหรับความเรียบง่ายจัดการทุกการกระทำในการเปิดรอบที่เพิ่มขึ้น มีการหมุน 3 แกนแต่ละทิศทางเป็นไปได้ 2 ทิศทางสำหรับการกระทำที่เป็นไปได้ทั้งหมด 6 รายการบนคิวบ์ ด้วยข้อมูลนี้มันจะกลายเป็นงานที่ค่อนข้างง่ายในการแมปการกระทำที่เป็นไปได้ 6 อย่างบนคิวบ์

ดังนั้นสีเขียวในด้าน 6 ตำแหน่ง 3 อาจเลื่อนไปด้านข้าง 1 ตำแหน่ง 3 หรือด้าน 2 ตำแหน่ง 7 ขึ้นอยู่กับการดำเนินการ ฉันไม่ได้สำรวจเรื่องนี้มากพอที่จะค้นหาคำแปลทางคณิตศาสตร์ใด ๆ แต่รูปแบบอาจจะปรากฏว่าคุณสามารถใช้ประโยชน์จากในรหัส

การใช้โครงสร้างข้อมูลฉันจะทราบได้อย่างไรว่าลูกบาศก์บางอย่างในสถานะที่แน่นอนสามารถแก้ไขได้? ฉันดิ้นรนกับคำถามนี้ด้วยตัวเองและยังไม่พบคำตอบเลย

เมื่อต้องการทำสิ่งนี้อย่าเริ่มต้นด้วยสถานะคิวบ์แบบสุ่ม แทนที่จะเริ่มต้นด้วยรัฐแก้ไขและดำเนินการnการกระทำของโปรแกรมที่จะได้รับก้อนเข้าสู่สถานะเริ่มต้นสุ่ม เนื่องจากคุณดำเนินการทางกฎหมายเพื่อไปยังสถานะปัจจุบันเท่านั้นจึงต้องแก้ไขคิวบ์ได้


1
คำแนะนำแบบคลาสสิก "คุณไม่ต้องการเริ่มจากตรงนี้"!
Ergwun

8

ฉันพบระบบพิกัด xyz เป็นวิธีที่ง่ายในการจัดการกับลูกบาศก์ของรูบิคและเมทริกซ์การหมุนเป็นวิธีทั่วไปที่ง่าย ๆ ในการใช้การหมุน

(x, y, z)ฉันสร้างชั้นชิ้นที่มีเวกเตอร์ตำแหน่ง ชิ้นส่วนสามารถหมุนได้โดยใช้เมทริกซ์การหมุนกับตำแหน่ง (การคูณเมทริกซ์เวกเตอร์) The Piece ยังเก็บแทร็กของสีไว้ใน tuple (cx, cy, cz)โดยให้สีหันไปตามแต่ละแกน จำนวนเล็กน้อยของตรรกะให้สีเหล่านี้มีการปรับปรุงอย่างเหมาะสมในระหว่างการหมุน: หมุน 90 องศาในระนาบ XY หมายความว่าเราจะสลับค่าของและcxcy

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

การนำไปใช้งานนี้ง่ายและมีสองตระกูล:

  1. ตำแหน่งของวัตถุชิ้นหนึ่งจะเปลี่ยนไป แต่สีของมันจะไม่เปลี่ยนแปลง ซึ่งหมายความว่าคุณสามารถขอชิ้นส่วนสีแดงสีเขียวแขวนบนวัตถุทำผลัดบางและตรวจสอบวัตถุเดียวกันเพื่อดูว่าชิ้นสีแดงสีเขียวจบลง
  2. ชิ้นส่วนแต่ละประเภท (ขอบตรงกลางมุม) มีรูปแบบการประสานงานที่ไม่ซ้ำกัน สำหรับลูกบาศก์ 3x3 ชิ้นส่วนมุมไม่มีศูนย์ในเวกเตอร์ตำแหน่ง ( (-1, 1, 1)) ขอบมีค่าเท่ากับหนึ่งศูนย์ ( (1, 0, -1)) และชิ้นส่วนกึ่งกลางมีศูนย์สองศูนย์ ( (-1, 0, 0))
  3. เมทริกซ์การหมุนที่ทำงานกับคิวบ์ 3x3 จะทำงานกับคิวบ์ NxN

ข้อเสีย:

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

3
ฉันพบว่าการใช้งานประเภทนี้ทำงานได้ดีที่สุดในการแสดงคิวบ์ในโปรแกรมกราฟิก 3D การคูณเมทริกซ์ทำให้สามารถเคลื่อนไหวการหมุนของเลเยอร์ได้ ดูrepo GitHub นี้สำหรับตัวอย่างการใช้วิธีการนี้ ฉันกำลังพิจารณาว่าจะเพิ่มตัวแก้ปัญหาให้กับคิวบ์สามมิติของฉันฉันต้องใช้อัลกอริทึมและโครงสร้างข้อมูลจากคำตอบอื่น
Jonathan Wilson

5

คุณสามารถใช้อาเรย์ง่าย ๆ (แต่ละองค์ประกอบมีการแมป 1 ถึง 1 กับสี่เหลี่ยมจัตุรัสบนใบหน้า) และจำลองการหมุนแต่ละครั้งด้วยการเปลี่ยนแปลง

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

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


1
the most straightforward way of know whether a cube is solvable is to solve it. การใช้แบบจำลองที่คุณแนะนำฉันคิดว่ามันเป็นเรื่องจริง แต่ถ้าคุณใช้แบบจำลองใกล้กับ @ maple_shaft's และการหมุนของแทร็กคุณสามารถทดสอบได้อย่างรวดเร็วว่าลูกบาศก์ 3x3x3 สามารถแก้ไขได้โดยการตรวจสอบผลรวมของ edge flips mod 2 คือ 0 และการหมุนมุม mod 3 คือ 0 จากนั้นตรวจสอบความเท่าเทียมกันของการเปลี่ยนแปลง การนับจำนวนการสลับขอบและการสลับมุม (จำเป็นต้องกลับไปแก้ไข), ผลรวม mod 2 ของพวกเขาจะต้องเป็น 0 (รวมเท่าเทียมกัน) นี่คือการทดสอบที่จำเป็นและเพียงพอเพื่อพิสูจน์ว่าลูกบาศก์สามารถแก้ไขได้
jimhark

3

เงื่อนไขแรกที่สามารถแก้ไขได้คือแต่ละชิ้นนั้นมีอยู่และสีในแต่ละชิ้นสามารถใช้เพื่อประกอบลูกบาศก์ "sovled" นี่เป็นเงื่อนไขที่ค่อนข้างเล็กน้อยซึ่งสามารถระบุความจริงได้ด้วยรายการตรวจสอบอย่างง่าย ชุดรูปแบบสีในคิวบ์ "มาตรฐาน" ถูกกำหนดไว้แต่แม้ว่าคุณจะไม่ได้ติดต่อกับคิวบ์มาตรฐานมีเพียง 6! การรวมกันที่เป็นไปได้ของใบหน้าที่แก้ไขแล้ว

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

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


1
สำหรับจุดที่ 2 แทนที่จะเริ่มต้นด้วยคิวบ์แบบสุ่มและตรวจสอบว่าสามารถแก้ไขได้หรือไม่ ฉันจะเริ่มต้นด้วยคิวบ์ที่แก้ไขแล้วและดำเนินการสุ่มบนคิวบ์เพื่อให้มันอยู่ในสถานะสุ่ม
Matthew Vines

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

2
คุณคาดเดาว่าอาจมี "เทคนิคแฟนซี" เพื่อพิจารณาว่าคิวบ์นั้นเป็นสิ่งที่สามารถแก้ไขได้หรือไม่ ในความเป็นจริงมี หากคุณแยกชิ้นส่วนของลูกบาศก์ แต่ให้เปิดสติกเกอร์แล้วประกอบชิ้นส่วนอีกครั้งคุณไม่จำเป็นต้องได้รับลูกบาศก์ที่สามารถแก้ไขได้ ในความเป็นจริงอัตราต่อรองเป็นหนึ่งถึงสิบสองต่อว่าคุณมีก้อนแก้ไขได้ คุณสามารถตรวจสอบว่าคุณอยู่ในสถานะที่แก้ไขได้ผ่านการวิเคราะห์ความเท่าเทียมกันของขอบและมุม; คุณไม่จำเป็นต้องพยายามแก้ปัญหาลูกบาศก์
Eric Lippert

1
ต่อไปนี้เป็นภาพรวมโดยย่อเกี่ยวกับคุณสมบัติการจับคู่ของคิวบ์สามชนิดที่ต้องได้รับการเก็บรักษาไว้เพื่อให้สามารถแก้ไขคิวบ์ได้ ryanheise.com/cube/cube_laws.html
Eric Lippert

1
ผมโพสต์คำถามว่าในเว็บไซต์การแข่งขัน stackexchange และมีคำตอบที่ดีจริงๆ: math.stackexchange.com/questions/127577/...
เมล

3

เนื่องจากคุณได้รับคำตอบที่ยอดเยี่ยมแล้วให้ฉันเพิ่มรายละเอียด

โดยไม่คำนึงถึงการเป็นรูปธรรมของคุณโปรดทราบว่าเลนส์เป็นเครื่องมือที่ดีมากสำหรับ "ซูมเข้า" ในส่วนต่างๆของลูกบาศก์ ตัวอย่างเช่นดูฟังก์ชันcycleLeftในรหัส Haskellนี้ มันเป็นฟังก์ชั่นทั่วไปที่ cyclically อนุญาตรายการใด ๆ ของความยาว 4 รหัสสำหรับการดำเนินการย้าย L มีลักษณะดังนี้:

moveL :: Aut (RubiksCube a)
moveL =
    cong cube $ cong leftCols cycleLeft
              . cong leftSide rotateSideCW

จึงcycleLeftดำเนินการในมุมมองที่ได้รับจาก leftColsในทำนองเดียวกันซึ่งเป็นฟังก์ชั่นการทั่วไปด้านข้างเป็นรุ่นที่หมุนของมันดำเนินการในมุมมองที่ได้รับจากrotateSideCW leftSideการเคลื่อนไหวอื่น ๆ สามารถดำเนินการในลักษณะที่คล้ายกัน

เป้าหมายของห้องสมุด Haskell คือการสร้างภาพสวย ๆ ฉันคิดว่ามันประสบความสำเร็จ: ไลบรารีไดอะแกรม-rubiks-cube กำลังทำงาน


2

คุณดูเหมือนจะถามคำถามสองข้อแยกกัน

  1. วิธีการแทนลูกบาศก์ที่มีจำนวนด้าน X เป็นอย่างไร

หากคุณจะจำลองลูกบาศก์รูบิคในโลกแห่งความเป็นจริงลูกบาศก์ของรูบิคทั้งหมดจะมี 6 ด้าน ฉันคิดว่าสิ่งที่คุณหมายถึงคือ "จำนวน X กระเบื้องต่อมิติต่อด้าน" แต่ละด้านของลูกบาศก์รูบิคดั้งเดิมคือ 3x3 ขนาดอื่น ๆ รวมถึง 4x4 (ศาสตราจารย์ของ Cube), 5x5 และ 6x6

ฉันจะแทนข้อมูลด้วย 6 ด้านโดยใช้สัญลักษณ์แก้ปัญหาคิวบ์ "มาตรฐาน":

  • ด้านหน้า: ใบหน้าหันเข้าหาตัวแก้ปัญหา
  • กลับ
  • ขวา
  • ซ้าย
  • UP
  • ลง

แต่ละด้านเป็นอาร์เรย์ 2 มิติของ X คูณ X


คุณสามารถซื้อลูกบาศก์ 17x17 ! มันมีการประนีประนอมเชิงกลบางอย่าง แต่มันมีความผิดปกติกับของจริง
RBerteig

1

ฉันชอบความคิดของ @maple_shaft เพื่อแสดงชิ้นส่วนต่าง ๆ (มินิคิวบ์) แตกต่างกัน: ชิ้นกลาง, ขอบและมุมมีสี 1, 2, หรือ 3 สีตามลำดับ

ฉันจะแสดงความสัมพันธ์ระหว่างพวกเขาเป็นกราฟ (แบบสองทิศทาง) โดยมีขอบเชื่อมต่อชิ้นส่วนที่อยู่ติดกัน แต่ละชิ้นจะมีช่องสำหรับขอบ (การเชื่อมต่อ): 4 ช่องในชิ้นกลาง, 4 ช่องในชิ้นส่วนขอบ, 3 ช่องในชิ้นมุม อีกทางหนึ่งชิ้นกลางอาจมีการเชื่อมต่อ 4 ชิ้นกับขอบชิ้นส่วนและ 4 สำหรับชิ้นส่วนมุมแยกจากกันและ / หรือชิ้นส่วนขอบอาจมี 2 ชิ้นเชื่อมต่อกับชิ้นส่วนกลางและ 2 ถึงชิ้นส่วนแยก

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

  • การค้นหาชิ้นส่วนที่เป็นของขอบเป็นเรื่องเล็กน้อย
  • การค้นหาชิ้นส่วนที่เป็นของใบหน้าเป็นเรื่องเล็กน้อย
  • การค้นหาใบหน้าที่อยู่ในทิศทางที่กำหนดไปยังใบหน้าที่กำหนดหรือใบหน้าที่ตรงข้ามกันคือการข้ามลิงค์ 2 หรือ 3 ที่กำหนดไว้อย่างดี
  • หากต้องการหมุนใบหน้าให้อัพเดตการเชื่อมต่อของชิ้นส่วนทั้งหมดที่เชื่อมต่อกับชิ้นส่วนกลางของใบหน้า

การตรวจจับเงื่อนไขที่ไม่สามารถแก้ไขได้อย่างชัดเจน (สลับเปลี่ยน / พลิกพลิกมุม) หากหวังว่าจะง่ายเช่นกันเพราะการค้นหาชิ้นส่วนบางประเภทและการวางแนวนั้นง่าย


1

แล้วโหนดและพอยน์เตอร์ล่ะ

สมมติว่ามี 6 ใบหน้าเสมอและ 1 โหนดนั้นหมายถึง 1 สี่เหลี่ยมจัตุรัสต่อ 1 หน้า:

r , g , b
r , g , b
r , g , b
|   |   |
r , g , b - r , g , b
r , g , b - r , g , b
r , g , b - r , g , b

โหนดมีตัวชี้ไปยังแต่ละโหนดถัดจากมัน การหมุนเป็นวงกลมเพียงแค่ย้ายตัวชี้ (จำนวนโหนด / จำนวนใบหน้า) -1 โหนดในกรณีนี้ 2 เนื่องจากการหมุนทั้งหมดเป็นการหมุนวนคุณเพียงแค่สร้างrotateฟังก์ชันเดียว เป็นการเรียกซ้ำย้ายแต่ละโหนดหนึ่งที่ว่างและตรวจสอบว่ามันเคลื่อนย้ายได้เพียงพอหรือไม่เนื่องจากมันจะรวบรวมจำนวนโหนดและมีใบหน้าสี่หน้าเสมอ หากไม่มีให้เพิ่มจำนวนครั้งที่ย้ายค่าแล้วหมุนโทรอีกครั้ง

อย่าลืมว่ามันมีการเชื่อมโยงเป็นสองเท่าดังนั้นโปรดอัปเดตโหนดแหลมใหม่เช่นกัน จะมีการย้ายจำนวนโหนดความสูง * ความกว้างเสมอโดยมีการอัปเดตตัวชี้หนึ่งตัวต่อโหนดดังนั้นควรมีการปรับปรุงจำนวนตัวชี้ความสูง * กว้าง * 2

เนื่องจากโหนดทั้งหมดชี้ไปที่กันและกันเพียงแค่เดินวนไปรอบ ๆ เพื่ออัพเดตแต่ละโหนดเมื่อคุณเข้ามา

สิ่งนี้ควรใช้กับคิวบ์ขนาดใดก็ได้โดยไม่มีเคสขอบหรือตรรกะที่ซับซ้อน มันเป็นเพียงแค่ตัวชี้เดิน / อัปเดต


-1

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

ลูกบาศก์ 4 คูณ 4 จะมี 12 ชุด 6 ชุดสำหรับใบหน้า 6 หน้าและ 6 ชุดสำหรับวงดนตรีหกวงที่ไปรอบ ๆ ลูกบาศก์ ใบหน้าแต่ละคนมี 16 ลูกย่อยและแต่ละวงมี 12 ลูกย่อย มีลูกบาศก์ย่อยทั้งหมด 56 ก้อน คิวบ์ย่อยแต่ละอันจะเก็บข้อมูลเกี่ยวกับสีและทิศทางของสี ลูกบาศก์รูบิคนั้นเป็นอาร์เรย์ขนาด 4 คูณ 4 คูณ 4 โดยแต่ละองค์ประกอบมีข้อมูลซึ่งประกอบด้วย 3 ชุดที่กำหนดคิวบ์ย่อยที่ตำแหน่งนั้น

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


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