ทูต , 51 ไบต์
{[3,3]&Rotate[Sample[{Sum@_=_2}&_\BinBelow@8]'_,4]}
ลองออนไลน์!
คำอธิบาย
เช่นเดียวกับคำตอบ J / APL ของ Galenเทคนิคพื้นฐานคือการสร้างอาร์เรย์ 1s และ 0s ด้วยจำนวนที่ถูกต้องของเหมืองการแทรกอินพุตโดยการผนวกเข้าไปที่ท้ายหมุนอาร์เรย์เช่นอินพุตอยู่ตรงกลางจากนั้น ก่อร่างใหม่เป็นเมทริกซ์ 3x3
ส่วนที่ 1: การสร้างอาร์เรย์แบบไบนารี
มีหลายวิธีที่จะทำสิ่งนี้ แต่ส่วนใหญ่ฉันเกิดขึ้นในสองประเภท: กำลังดุร้ายและการเลือก
วิธีเดรัจฉานกำลังหลักมีลักษณะเช่นนี้:
NestWhile[{Random[8&2]},0,{Sum@_/=_2}&_]
นี้จะสร้างอาร์เรย์แบบสุ่มของตัวเลข 8 หลักเลขฐานสอง ( Random[8&2]
) {Sum@_/=_2}&_
ในขณะที่ผลรวมของพวกเขาไม่เท่ากับการป้อนข้อมูล นี่เป็น verbose เล็กน้อยเนื่องจากบางส่วนของโค้ดที่เน้นดังต่อไปนี้อยู่ที่นั่น "เพื่อให้มันทำงาน":
NestWhile[{Random[8&2]},0,{Sum@_/=_2}&_]
^ ^^^^^ ^^^^
และฉันก็ยกเลิกความคิดนี้
การเลือกน่าสนใจยิ่งขึ้น แนวคิดหลักคือการใช้BaseBelow[b, n]
ในตัวซึ่งจะสร้างรายการ base- ทุกb
จำนวนเต็มของความกว้างn
(อาร์เรย์บาท) จากการ0
b^n-1
ตัวอย่างเช่นBaseBelow[3, 2]
สร้างจำนวนเต็มทั้งหมดของความกว้าง 2:
A> BaseBelow[3, 2]
0 0
0 1
0 2
1 0
1 1
1 2
2 0
2 1
2 2
เราใช้เฉพาะBaseBelow[2, 8]
สำหรับเลขจำนวนเต็มไบนารีทั้งหมดของความกว้าง 8 โดยเฉพาะเหล่านี้เป็นตัวแทนของเขตที่วางทุ่นระเบิดที่เป็นไปได้ของความยาวทั้งหมด นี่เป็นขั้นตอนแรก
ขั้นตอนที่สองคือการเลือกอาร์เรย์ดังกล่าวทั้งหมดด้วยN
1s เท่านั้นซึ่งN
เป็นอินพุต ความคิดแรกของฉันคือการแปลข้อความภาษาอังกฤษนี้เป็น Attache โดยตรง:
Chunk[SortBy[Sum,BaseBelow[2,8]],Sum]@N@1
อย่างไรก็ตามสิ่งนี้ไม่เพียง แต่จะมีความยาว 1 ไบต์มากกว่าวิธีการข้างต้นเท่านั้น แน่นอนว่าฉันสามารถบันทึก 1 ไบต์ได้ด้วยการจัดระเบียบวิธีการBaseBelow
เรียกใหม่ แต่ก็ไม่คุ้มกับการใช้วิธีการ
ดังนั้นฉันจึงตัดสินใจฆ่านกสองตัวด้วยหินก้อนเดียวและใช้Shuffle
วิธีการพื้นฐาน ข้อมูลต่อไปนี้ให้ความยาวที่ทุ่นระเบิดที่ถูกต้องทั้งหมดN
ตามลำดับแบบสุ่ม:
{Sum@_=_2}&N\Shuffle[BaseBelow&8!2]
จากนั้นทั้งหมดที่ต้องทำคือการเลือกแรก แต่ฉันสามารถทำได้ดีกว่า - แน่นอนว่ามันจะดีกว่าถ้าคุณSample
ใช้อาร์เรย์ที่กรองแล้ว วิธีการนี้ออกมาเป็นแบบนี้:
Sample[{Sum@_=_2}&_\BaseBelow[2,8]]
ฉันต้องเปลี่ยนกลับBaseBelow&8!2
กอล์ฟเพราะ\
ลำดับความสำคัญสูงเกินไป พอใจเป็นอย่างอื่นฉันดำเนินการสับไบต์จากที่:
Sample[{Sum@_=_2}&_\2&BaseBelow@8]
(ฉันค้นพบอีกวิธีหนึ่งในการเรียกฟังก์ชัน dyadic อย่างชัดเจนที่นี่: x&f@y
เป็นนิพจน์ที่มีลำดับความสำคัญสูงซึ่งประเมินf[x, y]
ได้)
อย่างไรก็ตามแม้จะมีนี้ผมจำได้ว่าตลอดนามแฝงสำหรับตัวตน:2&BaseBelow
BinBelow
ดังนั้นฉันใช้มัน:
Sample[{Sum@_=_2}&_\BinBelow@8]
สิ่งนี้จะสร้างทุ่นระเบิดที่ต้องการ ฉันเชื่อว่านี่ใกล้ดีที่สุดแล้ว
ส่วนที่ 2: การสร้างอาร์เรย์
ดังที่ได้กล่าวไปแล้วเทคนิคการขึ้นรูปที่ฉันใช้นั้นคล้ายกับคำตอบ J / APL ดังนั้นฉันจะไม่พูดถึงรายละเอียดมากเกินไป สมมติว่าMINEFIELD
เป็นผลลัพธ์จากส่วนสุดท้าย ฟังก์ชั่นจะกลายเป็น:
{[3,3]&Rotate[MINEFIELD'_,4]}
MINEFIELD'_
ต่อกับเขตที่วางทุ่นระเบิดกับอินพุตดั้งเดิม_
ทำให้เรามีลักษณะดังนี้:
[1, 0, 0, 0, 1, 0, 0, 1, 3]
จากนั้นRotate[MINEFIELD'_,4]
หมุนรายการนี้4
ไปทางซ้ายวางศูนย์กลาง:
[1, 0, 0, 1, 3, 1, 0, 0, 0]
ขั้นตอนสุดท้ายคือ[3,3]&
การเปลี่ยนรูปร่างรายการเป็นเมทริกซ์ 3x3:
1 0 0
1 3 1
0 0 0
1
และ0
?