ฟิชชัน , 1328 989 887 797 ไบต์
คำตอบนี้ยาวไปหน่อยอย่างไม่มีเหตุผล (ฉันหวังว่าเราจะมีพื้นที่ที่ยุบได้) ... โปรดอย่าลืมเลื่อนดูสิ่งนี้และแสดงคำตอบอื่น ๆ สำหรับความรัก!
การทำงานกับรหัสนี้เป็นสิ่งที่สร้างแรงบันดาลใจให้กับความท้าทายนี้ ฉันต้องการเพิ่มคำตอบใน Fission ให้กับ EOEIS ซึ่งทำให้ฉันอยู่ในลำดับนี้ อย่างไรก็ตามจริง ๆ แล้วการเรียนรู้การแบ่งเซลล์และการใช้งานสิ่งนี้ใช้เวลาสองสามสัปดาห์ในการเปิดและปิด ในขณะเดียวกันลำดับก็เพิ่มขึ้นอย่างมากกับฉันดังนั้นฉันตัดสินใจที่จะโพสต์ความท้าทายแยกต่างหากสำหรับมัน (บวกสิ่งนี้จะไม่ได้ลงไปที่ต้นไม้บน EOEIS ต่อไป)
ดังนั้นฉันจึงนำเสนอให้คุณความโหดร้าย:
R'0@+\
/ Y@</ /[@ Y]_L
[? % \ / \ J
\$@ [Z/;[{+++++++++L
UR+++++++++>/;
9\ ; 7A9
SQS {+L /$ \/\/\/\/\/ 5/ @ [~ &@[S\/ \ D /8/
~4X /A@[ %5 /; & K } [S//~KSA /
3 \ A$@S S\/ \/\/\/ \/>\ /S]@A / \ { +X
W7 X X /> \ +\ A\ / \ /6~@/ \/
/ ~A\; +;\ /@
ZX [K / {/ / @ @ } \ X @
\AS </ \V / }SZS S/
X ;;@\ /;X /> \ ; X X
; \@+ >/ }$S SZS\+; //\V
/ \\ /\; X X @ @ \~K{
\0X / /~/V\V / 0W//
\ Z [K \ //\
W /MJ $$\\ /\7\A /;7/\/ /
4}K~@\ &] @\ 3/\
/ \{ }$A/1 2 }Y~K <\
[{/\ ;@\@ / \@<+@^ 1;}++@S68
@\ <\ 2 ; \ /
$ ;}++ +++++++L
%@A{/
M \@+>/
~ @
SNR'0YK
\ A!/
คาดว่าจะไม่มีการขึ้นบรรทัดใหม่ของอินพุตดังนั้นคุณอาจต้องการเรียกว่าเป็นเช่นecho -n 120 | ./Fission oeis256504.fisนั้น
เลย์เอาต์อาจจะมีประสิทธิภาพมากกว่าดังนั้นฉันคิดว่ายังมีพื้นที่เหลือเฟือสำหรับการปรับปรุงที่นี่ (เช่นมี911 581 461 374 ช่องว่าง)
ก่อนที่เราจะไปถึงคำอธิบายให้ทราบเกี่ยวกับการทดสอบนี้: ล่ามอย่างเป็นทางการไม่ทำงานอย่างที่ ก) Mirror.cppไม่ได้รวบรวมในหลาย ๆ ระบบ หากคุณพบปัญหาดังกล่าวเพียงแค่คอมเม้นท์บรรทัดที่ละเมิด - ส่วนประกอบที่ได้รับผลกระทบ (มิรเรอร์แบบสุ่ม) จะไม่ถูกใช้ในรหัสนี้ b) มีข้อบกพร่องสองสามข้อที่สามารถนำไปสู่พฤติกรรมที่ไม่ได้กำหนด (และเป็นไปได้สำหรับโปรแกรมที่ซับซ้อนนี้) คุณสามารถใช้โปรแกรมแก้ไขนี้เพื่อแก้ไข เมื่อคุณทำสิ่งนั้นเสร็จแล้วคุณควรรวบรวมล่ามด้วย
g++ -g --std=c++11 *.cpp -o Fission
ความจริงที่สนุกสนาน: โปรแกรมนี้ใช้องค์ประกอบฟิชชันเกือบทุกอย่างที่มีให้ยกเว้น#(มิเรอร์แบบสุ่ม), :(มิเรอร์ครึ่งหนึ่ง) -หรือ|(มิเรอร์ธรรมดา) และ"(โหมดการพิมพ์)
เกิดอะไรขึ้นบนโลกนี้?
คำเตือน:นี่จะค่อนข้างนาน ... ฉันสมมติว่าคุณสนใจอย่างแท้จริงในเรื่องการทำงานของฟิชชันและวิธีที่โปรแกรมสามารถทำได้ เพราะถ้าคุณไม่ฉันไม่แน่ใจว่าฉันจะสรุปได้อย่างไร (ย่อหน้าถัดไปให้คำอธิบายทั่วไปของภาษาว่า)
ฟิชชันเป็นภาษาโปรแกรมสองมิติที่ทั้งข้อมูลและโฟลว์ควบคุมถูกแสดงโดยอะตอมที่เคลื่อนที่ผ่านกริด หากคุณเคยเห็นหรือเคยใช้Marbelousมาก่อนแนวคิดนี้น่าจะคุ้นเคย แต่ละอะตอมมีคุณสมบัติจำนวนเต็มสองอย่าง: มวลที่ไม่เป็นลบและพลังงานโดยพลการ หากมวลกลายเป็นลบอะตอมจะถูกลบออกจากกริด ในกรณีส่วนใหญ่คุณสามารถรักษามวลเป็น "ค่า" ของอะตอมและพลังงานเป็นคุณสมบัติเมตาบางประเภทที่ใช้โดยองค์ประกอบหลายอย่างเพื่อกำหนดการไหลของอะตอม (เช่นสวิตช์ส่วนใหญ่ขึ้นอยู่กับสัญลักษณ์ของ พลังงาน) ฉันจะแสดงอะตอมโดย(m,E)เมื่อจำเป็น ที่จุดเริ่มต้นของโปรแกรมตารางเริ่มต้นด้วยเครือ(1,0)อะตอมจากที่ใดก็ตามที่คุณวางบนส่วนประกอบทั้งสี่UDLR(ที่จดหมายระบุทิศทางที่อะตอมเคลื่อนที่ในตอนแรก) จากนั้นบอร์ดจะเต็มไปด้วยส่วนประกอบทั้งหมดซึ่งเปลี่ยนมวลและพลังงานของอะตอมเปลี่ยนทิศทางหรือทำสิ่งที่ซับซ้อนมากขึ้น สำหรับรายการทั้งหมดดูหน้า esolangsแต่ฉันจะแนะนำพวกเขาส่วนใหญ่ในคำอธิบายนี้ อีกจุดสำคัญ (ซึ่งโปรแกรมใช้หลายครั้ง) ก็คือตารางนั้นเป็น toroidal: อะตอมที่กระทบกับด้านใดด้านหนึ่งจะปรากฏขึ้นอีกด้านหนึ่งโดยเคลื่อนที่ไปในทิศทางเดียวกัน
ฉันเขียนโปรแกรมในชิ้นส่วนเล็ก ๆ หลาย ๆ ชิ้นและประกอบมันในตอนท้ายดังนั้นฉันจะอธิบายได้อย่างไร
atoi
ส่วนประกอบนี้อาจดูไม่น่าสนใจนัก แต่ก็ดีและเรียบง่ายและช่วยให้ฉันสามารถแนะนำแนวคิดที่สำคัญมากมายเกี่ยวกับเลขคณิตและโฟลว์การควบคุมของฟิชชัน ดังนั้นฉันจะผ่านส่วนนี้ในรายละเอียดที่พิถีพิถันมากดังนั้นฉันสามารถลดส่วนอื่น ๆ เพื่อแนะนำกลไกฟิชชันใหม่และชี้ให้เห็นส่วนประกอบระดับสูงที่มีการควบคุมการไหลแบบละเอียดที่คุณควรจะติดตามตัวเอง
ฟิชชันสามารถอ่านค่าไบต์จากอักขระแต่ละตัวเท่านั้นไม่ใช่ตัวเลขทั้งหมด ในขณะที่การปฏิบัติที่ยอมรับได้ที่นี่ฉันคิดในขณะที่ฉันอยู่ที่มันฉันสามารถทำได้ถูกต้องและแยกจำนวนเต็มจริงใน STDIN นี่คือatoiรหัส:
;
R'0@+\
/ Y@</ /[@ Y]_L
[? % \ / \ J
\$@ [Z/;[{+++++++++L
UR+++++++++>/;
O
สององค์ประกอบที่สำคัญที่สุดในฟิชชันคือฟิชชันและฟิวชั่นเครื่องปฏิกรณ์ เครื่องปฏิกรณ์ฟิชชันนั้นเป็นของอย่างใดอย่างหนึ่งV^<>(โค้ดด้านบนใช้<และ>) เครื่องปฏิกรณ์ฟิชชันสามารถเก็บอะตอม (โดยการส่งมันเข้าไปในตัวละครลิ่ม) (2,0)เริ่มต้นการเป็น หากอะตอมชนกับเอเพ็กซ์ของตัวละครอะตอมใหม่สองตัวจะถูกส่งออกไปที่ด้านข้าง มวลของพวกมันถูกกำหนดโดยการหารมวลที่เข้ามาด้วยมวลที่ถูกเก็บไว้ (เช่นลดลงครึ่งหนึ่งตามค่าเริ่มต้น) - อะตอมซ้ายไปจะได้รับค่านี้และอะตอมขวาไปจะได้รับส่วนที่เหลือของมวล . อะตอมทั้งสองจะมีพลังงานขาเข้าลบออกพลังงานที่เก็บไว้ ซึ่งหมายความว่าเราสามารถใช้เครื่องปฏิกรณ์ฟิชชันสำหรับเลขคณิต - ทั้งสำหรับการลบและการหาร หากเครื่องปฏิกรณ์ฟิชชันถูกโจมตีจากไซต์อะตอมก็จะสะท้อนให้เห็นในแนวทแยงมุมและจากนั้นจะเคลื่อนที่ไปในทิศทางของยอดของตัวละคร
เครื่องปฏิกรณ์ฟิวชั่นเป็นของใด ๆYA{}(รหัสข้างต้นใช้Yและ{) ฟังก์ชั่นของพวกเขาคล้ายกัน: พวกเขาสามารถเก็บอะตอม (ค่าเริ่มต้น(1,0)) และเมื่อถูกชนจากยอดสองอะตอมใหม่จะถูกส่งออกไปด้านข้าง อย่างไรก็ตามในกรณีนี้ทั้งสองอะตอมจะเหมือนกันเสมอรักษาพลังงานที่เข้ามาและคูณมวลที่เข้ามาโดยมวลที่เก็บไว้ นั่นคือโดยปกติเครื่องปฏิกรณ์ฟิวชั่นจะทำซ้ำอะตอมใด ๆ ที่กระทบยอด เมื่อถูกชนจากด้านข้างเครื่องปฏิกรณ์ฟิวชั่นนั้นซับซ้อนกว่าเล็กน้อย: อะตอมก็เช่นกันเก็บไว้ (เป็นอิสระจากหน่วยความจำอื่น) จนกระทั่งอะตอมชนกับด้านตรงข้าม เมื่อสิ่งนั้นเกิดขึ้นอะตอมใหม่จะถูกปล่อยออกมาในทิศทางของยอดที่มีมวลและพลังงานเป็นผลรวมของอะตอมเก่าสองอะตอม หากอะตอมใหม่ชนกับด้านเดียวกันก่อนที่อะตอมที่เข้าคู่จะถึงด้านตรงข้ามอะตอมเก่าก็จะถูกเขียนทับ เครื่องปฏิกรณ์ฟิวชั่นสามารถใช้เพื่อเพิ่มและคูณ
อีกองค์ประกอบที่เรียบง่ายที่ฉันต้องการหลีกทางคือ[และ]กำหนดทิศทางของอะตอมไปทางขวาและซ้ายตามลำดับ (โดยไม่คำนึงถึงทิศทางที่เข้ามา) ค่าเทียบเท่าแนวตั้งคือM(ลง) และW(ขึ้น) แต่ไม่ได้ใช้กับatoiรหัส UDLRทำหน้าที่เหมือนWM][หลังจากปล่อยอะตอมเริ่มต้นของพวกเขา
เอาล่ะลองดูโค้ดที่นั่น โปรแกรมเริ่มต้นด้วย 5 อะตอม:
RและLที่ด้านล่างเพียงได้รับการเพิ่มมวลของพวกเขา (กับ+) จะกลายเป็น(10,0)แล้วเก็บไว้ในการแบ่งเซลล์และเครื่องปฏิกรณ์ฟิวชั่นตามลำดับ เราจะใช้เครื่องปฏิกรณ์เหล่านี้เพื่อวิเคราะห์อินพุต -10
Lในมุมขวาด้านบนได้รับมวล decremented (กับ_) จะกลายเป็นและถูกเก็บไว้ในด้านข้างของเครื่องปฏิกรณ์ฟิวชั่น(0,0) Yนี่คือการติดตามจำนวนที่เรากำลังอ่านเราจะค่อยๆเพิ่มและทวีคูณเมื่อเราอ่านตัวเลข
Rในมุมซ้ายด้านบนได้รับมวลของมันตั้งค่ารหัสอักขระของ0(48) ด้วย'0แล้วมวลและพลังงานจะสลับกับ@และในที่สุดก็เพิ่มขึ้นมวลครั้งด้วยที่จะให้+ (1,48)จากนั้นจะถูกเปลี่ยนเส้นทางด้วยกระจกแนวทแยงมุม\และ/เก็บไว้ในเครื่องปฏิกรณ์ฟิชชัน เราจะใช้การ48ลบเพื่อเปลี่ยนข้อมูล ASCII ให้เป็นค่าจริงของตัวเลข นอกจากนี้เรายังมีการเพิ่มมวลเพื่อที่จะหลีกเลี่ยงการหารด้วย10
- ในที่สุดที่
Uมุมซ้ายล่างคือสิ่งที่ทำให้ทุกอย่างเคลื่อนไหวและเริ่มใช้เพื่อควบคุมการไหลเท่านั้น
หลังจากถูกเปลี่ยนเส้นทางไปทางขวาอะตอมควบคุมจะเข้า?สู่ นี่คือองค์ประกอบอินพุต มันอ่านตัวอักษรและการตั้งค่ามวลอะตอมของกับค่า ASCII 0การอ่านและพลังงานในการ ถ้าเราตี EOF 1แทนพลังงานจะถูกตั้งค่า
อะตอมยังคงดำเนินต่อ%ไป นี่คือสวิตช์กระจก สำหรับพลังงานที่ไม่เป็นบวกสิ่งนี้ทำหน้าที่เหมือน/กระจกเงา แต่สำหรับพลังงานบวกมันทำหน้าที่เหมือน\(และยังลดพลังงานลง 1) ดังนั้นในขณะที่เรากำลังอ่านตัวละครอะตอมจะสะท้อนขึ้นและเราสามารถประมวลผลตัวละคร แต่เมื่อเราทำกับอินพุตอะตอมจะสะท้อนลงและเราสามารถใช้ตรรกะต่าง ๆ เพื่อดึงผลลัพธ์ FYI &องค์ประกอบตรงข้ามคือ
ตอนนี้เรามีอะตอมที่เคลื่อนที่ได้แล้ว สิ่งที่เราต้องการทำสำหรับตัวละครแต่ละตัวคือการอ่านค่าหลักของมันเพิ่มเข้าไปในผลรวมสะสมของเราแล้วคูณด้วยจำนวนผลรวม 10 เพื่อเตรียมพร้อมสำหรับหลักถัดไป
อะตอมตัวอักษรตัวแรกฮิต (เริ่มต้น) Yเครื่องปฏิกรณ์ฟิวชั่น สิ่งนี้จะแยกอะตอมและเราใช้สำเนาซ้ายไปเป็นอะตอมควบคุมเพื่อวนกลับเข้าไปในองค์ประกอบอินพุตและอ่านอักขระถัดไป สำเนาที่ถูกต้องจะถูกดำเนินการ 3พิจารณากรณีที่เราได้อ่านตัวอักษร อะตอมของเราจะเป็น(51,0)อย่างไร เราแลกเปลี่ยนมวลและพลังงานด้วย@เช่นนั้นเราสามารถใช้การลบของเครื่องปฏิกรณ์ฟิชชันถัดไป เครื่องปฏิกรณ์ลบ48พลังงานออก (โดยไม่ต้องเปลี่ยนมวล) ดังนั้นมันจึงส่งออกไปสองชุด(0,3)- ตอนนี้พลังงานสอดคล้องกับหลักที่เราอ่าน สำเนาที่อยู่ข้างบนจะถูกยกเลิกเพียงแค่;(ส่วนประกอบที่เพิ่งทำลายอะตอมขาเข้าทั้งหมด) เราจะทำงานกับสำเนาต่อไป คุณจะต้องทำตามเส้นทางผ่าน/และ\กระจกเล็กน้อย
@เพียงก่อนที่เครื่องปฏิกรณ์ฟิวชั่น swaps มวลและพลังงานอีกครั้งเช่นที่เราจะเพิ่มการรวมการทำงานของเราใน(3,0) Yโปรดทราบว่าผลรวมการรันเองจะมี0พลังงานเสมอ
ตอนนี้Jเป็นกระโดด สิ่งที่มันจะกระโดดอะตอมที่เข้ามาใด ๆ ไปข้างหน้าด้วยพลังงานของมัน ถ้าเป็น0เช่นนั้นอะตอมก็จะเคลื่อนที่ต่อไปเรื่อย ๆ ถ้ามัน1จะข้ามเซลล์หนึ่งถ้า2มันจะข้ามสองเซลล์และอื่น ๆ 0พลังงานที่ใช้ในการกระโดดดังนั้นอะตอมมักจะจบลงด้วยการใช้พลังงาน นับตั้งแต่การรวมการทำงานจะมีศูนย์พลังงานกระโดดจะถูกละเว้นสำหรับในตอนนี้และอะตอมจะถูกนำเข้าสู่เครื่องปฏิกรณ์ฟิวชั่นซึ่งคูณมวลของมันโดย{ 10สำเนาที่ถูกตัดทิ้งจะถูกทิ้ง;ในขณะที่สำเนาที่ส่งกลับจะถูกป้อนกลับเข้าไปในYเครื่องปฏิกรณ์เป็นผลรวมการดำเนินการใหม่
ด้านบนยังคงทำซ้ำ (ในลักษณะที่สนุกสนานไปป์ไลน์ที่มีการประมวลผลตัวเลขใหม่ก่อนที่จะทำก่อนหน้านี้) จนกว่าเราจะกด EOF ตอนนี้%จะส่งอะตอมลง ความคิดที่จะเปิดอะตอมนี้ใน(0,1)ตอนนี้ก่อนกดปุ่มเครื่องปฏิกรณ์รวมการทำงานเพื่อให้) ทั้งหมดที่ไม่ได้รับผลกระทบ (ศูนย์มวล) และ b) เราได้รับพลังงานจากการกระโดดข้าม1 [เราสามารถดูแลพลังงานได้อย่างง่ายดายด้วย$ซึ่งจะเป็นการเพิ่มพลังงาน
ปัญหาคือ?ไม่ได้รีเซ็ตมวลเมื่อคุณกด EOF ดังนั้นมวลจะยังคงเป็นตัวอักษรสุดท้ายที่อ่านและพลังงานจะเป็น0(เพราะ%ลดค่า1กลับไป0) เราอยากกำจัดมวลนั้น เมื่อต้องการทำเช่นนั้นเราจะเปลี่ยนมวลและพลังงานด้วย@อีกครั้ง
Zฉันต้องการที่จะแนะนำองค์ประกอบหนึ่งมากขึ้นก่อนที่จะจบขึ้นส่วนนี้: นี้เป็นหลักเช่นเดียวกับหรือ% &ความแตกต่างคือช่วยให้อะตอมพลังงานบวกผ่าน (ในขณะที่ลดพลังงาน) และเบี่ยงเบนอะตอมที่ไม่ใช่พลังงานบวก 90 องศาไปทางซ้าย เราสามารถใช้สิ่งนี้เพื่อกำจัดพลังงานของอะตอมโดยการวนซ้ำZไปเรื่อย ๆ - ทันทีที่พลังงานหมดไปอะตอมก็จะเบี่ยงเบนและออกจากวง นั่นคือรูปแบบนี้:
/ \
[Z/
ที่ซึ่งอะตอมจะเคลื่อนที่ขึ้นเมื่อพลังงานเป็นศูนย์ ฉันจะใช้รูปแบบนี้ในรูปแบบเดียวหรือหลายครั้งในส่วนอื่น ๆ ของโปรแกรม
ดังนั้นเมื่ออะตอมออกจากลูปเล็ก ๆ นี้มันจะถูก(1,0)เปลี่ยนเป็น(0,1)โดย@ก่อนที่จะกดปุ่มเครื่องปฏิกรณ์ฟิวชั่นเพื่อปล่อยผลสุดท้ายของอินพุต อย่างไรก็ตามผลรวมการทำงานจะถูกปิดโดยปัจจัย 10 เนื่องจากเราได้คูณจำนวนนั้นกับตัวเลขอื่นแล้ว
ดังนั้นตอนนี้มีพลังงาน1อะตอมนี้จะข้ามและกระโดดลงไปใน[ /สิ่งนี้เบี่ยงเบนมันไปเป็นเครื่องปฏิกรณ์ฟิชชันซึ่งเราได้เตรียมที่จะหารด้วย 10 และแก้ไขการคูณภายนอกของเรา อีกครั้งเราละทิ้งครึ่งหนึ่ง;และเก็บไว้เป็นเอาท์พุท (ที่นี่เป็นตัวOแทนที่จะพิมพ์ตัวละครที่สอดคล้องกันและทำลายอะตอม - ในโปรแกรมเต็มรูปแบบที่เราให้ใช้อะตอมแทน)
itoa
/ \
input -> [{/\ ;@
@\ <\
$ ;}++ +++++++L
%@A{/
M \@+>/
~ @
SNR'0YK
\ A!/
แน่นอนเรายังต้องแปลงผลลัพธ์กลับเป็นสตริงและพิมพ์ นั่นคือสิ่งที่ส่วนนี้มีไว้สำหรับ สมมติว่าอินพุตไม่มาถึงก่อนขีด 10 หรือมากกว่านั้น แต่ในโปรแกรมเต็มรูปแบบที่ให้มาได้อย่างง่ายดาย บิตนี้สามารถพบได้ที่ด้านล่างของโปรแกรมเต็มรูปแบบ
รหัสนี้จะแนะนำองค์ประกอบฟิชชันใหม่ที่ทรงพลังมาก: สแต็Kก สแต็กแรกว่างเปล่า เมื่ออะตอมที่มีพลังงานไม่เป็นลบกระทบกับสแต็กอะตอมจะถูกผลักลงบนสแต็ก เมื่ออะตอมที่มีพลังงานเป็นลบกระทบกับสแต็คมวลและพลังงานของมันจะถูกแทนที่ด้วยอะตอมที่อยู่ด้านบนของสแต็ค หากสแต็คว่างเปล่าแม้ว่าทิศทางของอะตอมจะกลับกันและพลังงานของมันจะกลายเป็นบวก (เช่นคูณด้วย-1)
ตกลงกลับไปที่รหัสจริง แนวคิดของitoaตัวอย่างคือการใช้อินพุทโมดูโล 10 ซ้ำ ๆ เพื่อค้นหาตัวเลขถัดไปในขณะที่จำนวนเต็มหารด้วย 10 สำหรับการวนซ้ำครั้งถัดไป สิ่งนี้จะให้ตัวเลขทั้งหมดในลำดับย้อนกลับ (จากนัยสำคัญน้อยที่สุดถึงสำคัญที่สุด) ในการแก้ไขคำสั่งเราจะส่งตัวเลขทั้งหมดไปที่สแต็ก
ครึ่งบนของโค้ดทำการคำนวณหลัก: Lด้วย pluses ให้ 10 ซึ่งเราโคลนและป้อนเข้าสู่ฟิชชันและเครื่องปฏิกรณ์ฟิวชั่นเพื่อให้เราสามารถหารและคูณด้วย 10 ห่วงเริ่มต้น[จากมุมซ้ายบน . ค่าปัจจุบันถูกแบ่ง: หนึ่งสำเนาถูกหารด้วย 10 จากนั้นคูณด้วย 10 และเก็บไว้ในเครื่องปฏิกรณ์ฟิชชัน นี้คำนวณเป็นi % 10 i - ((i/10) * 10)โปรดทราบว่าการAแบ่งผลกลางหลังจากการหารและก่อนการคูณดังนั้นเราสามารถป้อนi / 10เข้าไปในการวนซ้ำครั้งถัดไป
%ยกเลิกห่วงเมื่อตัวแปรซ้ำฮิต 0. ตั้งแต่นี้จะมากหรือน้อยวงทำในขณะนี้รหัสนี้แม้จะทำงานสำหรับการพิมพ์0(โดยไม่ต้องสร้างศูนย์ชั้นนำอื่น ๆ ) เมื่อเราออกจากวงเราต้องการที่จะล้างกองและพิมพ์ตัวเลข Sอยู่ตรงข้ามZดังนั้นจึงเป็นสวิตช์ที่จะเบี่ยงเบนอะตอมที่เข้ามาด้วยพลังงานที่ไม่เป็นบวก 90 องศาไปทางขวา ดังนั้นอะตอมเคลื่อนไปตามขอบจากทางSตรงไปยังที่Kจะโผล่ออกมาเป็นหลัก (หมายเหตุ~ซึ่งช่วยให้แน่ใจว่าอะตอมที่เข้ามามีพลังงาน-1) ตัวเลขนั้นจะถูกเพิ่มค่าโดย48รับรหัส ASCII ของอักขระหลักที่เกี่ยวข้อง Aแยกหลักในการพิมพ์สำเนาด้วย!และป้อนสำเนาอื่น ๆ กลับเข้าไปในYเครื่องปฏิกรณ์สำหรับตัวเลขถัดไป สำเนาที่พิมพ์จะถูกใช้เป็นทริกเกอร์ถัดไปสำหรับสแต็ก (โปรดทราบว่ามิรเรอร์จะส่งมันไปรอบ ๆ ขอบเพื่อชนMจากด้านซ้าย)
เมื่อสแต็คเป็นที่ว่างเปล่าที่Kจะสะท้อนให้เห็นถึงอะตอมและเปิดพลังงานของมันเข้าไปเช่นว่ามันผ่านตรงผ่าน+1 พิมพ์บรรทัดใหม่ (เพราะมันเป็นระเบียบ :)) และจากนั้นอะตอมไป thorugh อีกครั้งเพื่อจบลงในด้านของ เนื่องจากไม่มีอะตอมอยู่รอบ ๆ สิ่งนี้จะไม่ถูกปล่อยออกมาและโปรแกรมจะสิ้นสุดลงSNR'0Y
การคำนวณหมายเลขฟิชชัน: The Framework
ไปที่เนื้อของโปรแกรมกันเถอะ รหัสนั้นเป็นพอร์ตของการใช้การอ้างอิง Mathematica ของฉัน:
fission[n_] := If[
(div =
SelectFirst[
Reverse@Divisors[2 n],
(OddQ@# == IntegerQ[n/#]
&& n/# > (# - 1)/2) &
]
) == 1,
1,
1 + Total[fission /@ (Range@div + n/div - (div + 1)/2)]
]
โดยที่divเป็นจำนวนเต็มในพาร์ติชันสูงสุด
ความแตกต่างที่สำคัญคือเราไม่สามารถจัดการกับค่าครึ่งจำนวนเต็มในฟิชชันได้ดังนั้นฉันจึงทำหลายสิ่งหลายอย่างคูณด้วยสองและไม่มีการเรียกซ้ำในฟิชชัน เพื่อหลีกเลี่ยงปัญหานี้ฉันกำลังผลักจำนวนเต็มทั้งหมดในพาร์ติชันในคิวเพื่อประมวลผลในภายหลัง สำหรับแต่ละหมายเลขที่เราดำเนินการเราจะเพิ่มตัวนับหนึ่งและเมื่อคิวว่างเปล่าเราจะปล่อยตัวนับและส่งออกเพื่อพิมพ์ (คิวQทำงานเหมือนKกันตามลำดับ FIFO)
นี่คือกรอบการทำงานสำหรับแนวคิดนี้:
+--- input goes in here
v
SQS ---> compute div from n D /8/
~4X | /~KSA /
3 +-----------> { +X
initial trigger ---> W 6~@/ \/
4
W ^ /
| 3
^ generate range |
| from n and div <-+----- S6
| -then-
+---- release new trigger
ส่วนประกอบใหม่ที่สำคัญที่สุดคือตัวเลข นี่คือเครื่องเคลื่อนย้ายมวลสาร เครื่องเคลื่อนย้ายมวลสารทั้งหมดที่มีตัวเลขเดียวกันอยู่ด้วยกัน เมื่ออะตอมไปถึงเครื่องเคลื่อนย้ายมวลสารใด ๆ เครื่องจะเคลื่อนย้ายเครื่องเคลื่อนย้ายมวลสารถัดไปในกลุ่มเดียวกันทันทีโดยที่เครื่องถัดไปจะถูกกำหนดตามลำดับจากซ้ายไปขวาตามลำดับจากบนลงล่าง สิ่งเหล่านี้ไม่จำเป็น แต่ช่วยในการจัดวาง (และการเล่นกอล์ฟสักเล็กน้อย) นอกจากนี้ยังXมีการทำซ้ำอะตอมเพียงแค่ส่งสำเนาหนึ่งตรงไปข้างหน้าและข้างหลัง
ถึงตอนนี้คุณอาจจะสามารถแยกแยะกรอบงานส่วนใหญ่ออกมาได้ด้วยตัวเอง มุมซ้ายบนมีคิวของค่าที่ยังคงถูกประมวลผลและปล่อยทีnละครั้ง สำเนาหนึ่งของnถูกเคลื่อนย้ายไปด้านล่างเพราะเราต้องการเมื่อคำนวณช่วงสำเนาอื่น ๆ จะเข้าสู่บล็อกที่ด้านบนซึ่งคำนวณdiv(นี่คือส่วนที่ใหญ่ที่สุดของรหัส) เมื่อdivได้รับการคำนวณก็จะซ้ำ - Kหนึ่งสำเนาเพิ่มเคาน์เตอร์ในมุมขวาด้านบนซึ่งถูกเก็บไว้ใน สำเนาอื่นจะถูกส่งไปที่ด้านล่าง ถ้าdivเป็น1เช่นนั้นเราเบี่ยงเบนมันขึ้นมาทันทีและใช้มันเป็นทริกเกอร์สำหรับการทำซ้ำครั้งถัดไปโดยไม่ต้องจัดคิวค่าใหม่ใด ๆ มิฉะนั้นเราจะใช้divและn ในส่วนที่ด้านล่างเพื่อสร้างช่วงใหม่ (เช่นกระแสของอะตอมที่มีมวลที่สอดคล้องกันซึ่งจะถูกใส่ในคิว) จากนั้นปล่อยทริกเกอร์ใหม่หลังจากช่วงเสร็จสมบูรณ์
เมื่อคิวว่างเปล่าไกจะสะท้อนให้เห็นผ่านตรงผ่านSและโผล่มาให้เห็นในมุมขวาด้านบนที่มันออกเคาน์เตอร์ (ผลสุดท้าย) จากAซึ่งหายตัวไปแล้วผ่านทางitoa8
การคำนวณหมายเลขฟิชชัน: The Loop Body
ดังนั้นสิ่งที่เหลืออยู่คือสองส่วนในการคำนวณdivและสร้างช่วง การคำนวณdivเป็นส่วนนี้:
;
{+L /$ \/\/\/\/\/ 5/ @ [~ &@[S\/ \
/A@[ %5 /; & K } [S/
\ A$@S S\/ \/\/\/ \/>\ /S]@A / \
X X /> \ +\ A\ / \ /
/ ~A\; +;\ /@
ZX [K / {/ / @ @ } \ X @
\AS </ \V / }SZS S/
X ;;@\ /;X /> \ ; X X
\@+ >/ }$S SZS\+; //\V
/ \\ /\; X X @ @ \~K{
\0X / /~/V\V / 0W//
\ Z [K \ //\
\ /\7\A /;7/\/
คุณอาจเห็นพอที่จะไขปริศนาตัวเองด้วยความอดทน รายละเอียดระดับสูงคือ: 12 2nคอลัมน์แรกหรือเพื่อสร้างกระแสของตัวหารของ 10 OddQ@# == IntegerQ[n/#]คอลัมน์ต่อไปกรองผู้ที่ไม่ตอบสนอง ถัดไป 8 n/# > (# - 1)/2)คอลัมน์กรองผู้ที่ไม่ตอบสนอง ในที่สุดเราก็ผลักดันตัวหารที่ถูกต้องทั้งหมดลงบนสแต็กและเมื่อเราเสร็จแล้วเราจะลบสแต็กทั้งหมดลงในเครื่องปฏิกรณ์ฟิวชั่น (เขียนทับทั้งหมดยกเว้นตัวหารสุดท้าย / ตัวใหญ่ที่สุด) แล้วปล่อยผลลัพธ์ตามด้วยการกำจัดพลังงาน - ศูนย์จากการตรวจสอบความไม่เท่าเทียมกัน)
มีเส้นทางบ้ามากมายที่นั่นไม่ทำอะไรเลย ส่วนใหญ่\/\/\/\/ความบ้าคลั่งที่ด้านบน ( 5s นั้นก็เป็นส่วนหนึ่งของมัน) และหนึ่งเส้นทางรอบด้านล่าง (ที่ผ่าน7s) ฉันต้องเพิ่มสิ่งเหล่านี้เพื่อจัดการกับสภาพการแข่งขันที่น่ารังเกียจ ฟิชชันสามารถใช้องค์ประกอบการหน่วงเวลา ...
รหัสที่สร้างช่วงใหม่จากnและdivนี่คือ:
/MJ $$\
4}K~@\ &] @\ 3/\
\{ }$A/1 2 }Y~K <\
\@ / \@<+@^ 1;}++@
2 ; \ /
เราคำนวณครั้งแรกn/div - (div + 1)/2(คำศัพท์ทั้งคู่ปูพื้นซึ่งให้ผลลัพธ์เหมือนกัน) และเก็บไว้ใช้ในภายหลัง จากนั้นเราจะสร้างช่วงจากdivล่างลงไป1และเพิ่มค่าที่เก็บไว้ในแต่ละช่วง
มีรูปแบบทั่วไปสองแบบใหม่ในทั้งสองรูปแบบที่ฉันควรกล่าวถึง: รูปแบบหนึ่งคือSXหรือZXถูกกดจากด้านล่าง นี่เป็นวิธีที่ดีในการทำซ้ำอะตอมหากคุณต้องการสำเนาหนึ่งชุดเพื่อไปข้างหน้าทันที SหรือZหมุนอะตอมเข้าที่Xแล้วหมุนสำเนามิเรอร์กลับเข้ามาในทิศทางเดิมของการขยายพันธุ์
อีกแบบคือ
[K
\A --> output
ถ้าเราเก็บค่าใด ๆ ไว้ในKนั้นเราก็สามารถดึงมันกลับมาได้โดยการกดปุ่มKด้วยพลังงานเชิงลบจากด้านบน การAทำซ้ำค่าที่เราสนใจและส่งสิ่งที่คัดลอกกลับไปที่สแต็คในครั้งต่อไปที่เราต้องการ
นั่นเป็นเรื่องที่ค่อนข้าง ... แต่ถ้าคุณผ่านเรื่องนี้ไปได้จริงฉันหวังว่าคุณจะมีความคิดที่ว่าฟิชชันi͝s̢̘̗̗ ͢i̟nç̮̩r̸̭̬̱͔e̟̹̟̜͟d̙i̠͙͎̖͓̯b̘̠͎̭̰̼l̶̪̙̮̥̮y̠̠͎̺̠̠͎̺͜͜