ฟิชชัน , 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 ให้เป็นค่าจริงของตัวเลข นอกจากนี้เรายังมีการเพิ่มมวลเพื่อที่จะหลีกเลี่ยงการหารด้วย1
0
- ในที่สุดที่
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 อีกครั้งเพื่อจบลงในด้านของ เนื่องจากไม่มีอะตอมอยู่รอบ ๆ สิ่งนี้จะไม่ถูกปล่อยออกมาและโปรแกรมจะสิ้นสุดลงS
N
R'0
Y
การคำนวณหมายเลขฟิชชัน: 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
ซึ่งหายตัวไปแล้วผ่านทางitoa
8
การคำนวณหมายเลขฟิชชัน: 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)
คอลัมน์กรองผู้ที่ไม่ตอบสนอง ในที่สุดเราก็ผลักดันตัวหารที่ถูกต้องทั้งหมดลงบนสแต็กและเมื่อเราเสร็จแล้วเราจะลบสแต็กทั้งหมดลงในเครื่องปฏิกรณ์ฟิวชั่น (เขียนทับทั้งหมดยกเว้นตัวหารสุดท้าย / ตัวใหญ่ที่สุด) แล้วปล่อยผลลัพธ์ตามด้วยการกำจัดพลังงาน - ศูนย์จากการตรวจสอบความไม่เท่าเทียมกัน)
มีเส้นทางบ้ามากมายที่นั่นไม่ทำอะไรเลย ส่วนใหญ่\/\/\/\/
ความบ้าคลั่งที่ด้านบน ( 5
s นั้นก็เป็นส่วนหนึ่งของมัน) และหนึ่งเส้นทางรอบด้านล่าง (ที่ผ่าน7
s) ฉันต้องเพิ่มสิ่งเหล่านี้เพื่อจัดการกับสภาพการแข่งขันที่น่ารังเกียจ ฟิชชันสามารถใช้องค์ประกอบการหน่วงเวลา ...
รหัสที่สร้างช่วงใหม่จาก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̠̠͎̺̠̠͎̺͜͜