ทูต , 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 โดยเฉพาะเหล่านี้เป็นตัวแทนของเขตที่วางทุ่นระเบิดที่เป็นไปได้ของความยาวทั้งหมด นี่เป็นขั้นตอนแรก
ขั้นตอนที่สองคือการเลือกอาร์เรย์ดังกล่าวทั้งหมดด้วยN1s เท่านั้นซึ่ง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?