विखंडन , 1328 989 887 797 बाइट्स
यह उत्तर थोड़ा अनुचित रूप से लंबा है (काश हमारे पास समाप्त क्षेत्र होते ) ... कृपया इस अतीत को स्क्रॉल करना न भूलें और दूसरे जवाबों को थोड़ा प्यार करें!
इस कोड पर काम करना इस चुनौती से प्रेरित था। मैं Fission में 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
कई प्रणालियों पर संकलन नहीं करता है। यदि आप उस समस्या में भाग लेते हैं, तो आपत्तिजनक लाइन पर टिप्पणी करें - इस कोड में प्रभावित घटक (एक यादृच्छिक दर्पण) का उपयोग नहीं किया गया है। बी) कुछ ऐसे कीड़े हैं जो अपरिभाषित व्यवहार का नेतृत्व कर सकते हैं (और इस कार्यक्रम के लिए संभावना होगी)। आप उन्हें ठीक करने के लिए इस पैच को लगा सकते हैं। एक बार जब आप ऐसा कर लेते हैं, तो आपको दुभाषिया को संकलित करने में सक्षम होना चाहिए
g++ -g --std=c++11 *.cpp -o Fission
मजेदार तथ्य: यह कार्यक्रम लगभग हर घटक का उपयोग करता है विखंडन #
(यादृच्छिक दर्पण), :
(आधा दर्पण), -
या |
(सादा दर्पण), और "
(प्रिंट मोड) को छोड़कर, की पेशकश करनी है ।
पृथ्वी पर क्या?
चेतावनी: यह काफी लंबा होगा ... मुझे लगता है कि आप वास्तव में रुचि रखते हैं कि विखंडन कैसे काम करता है और इसमें कोई कैसे कार्यक्रम कर सकता है। क्योंकि यदि आप नहीं हैं, तो मुझे यकीन नहीं है कि मैं इसे कैसे संक्षेप में बता सकता हूं। (अगला पैराग्राफ हालांकि भाषा का एक सामान्य विवरण देता है।)
विखंडन एक दो-आयामी प्रोग्रामिंग भाषा है, जहां डेटा और नियंत्रण प्रवाह दोनों का प्रतिनिधित्व ग्रिड के माध्यम से जाने वाले परमाणुओं द्वारा किया जाता है। यदि आपने पहले मारबेलस देखा या उपयोग किया है , तो अवधारणा को पूरी तरह से परिचित होना चाहिए। प्रत्येक परमाणु में दो पूर्णांक गुण होते हैं: एक गैर-नकारात्मक द्रव्यमान और एक मनमाना ऊर्जा। यदि द्रव्यमान कभी ऋणात्मक हो जाता है तो परमाणु को ग्रिड से हटा दिया जाता है। ज्यादातर मामलों में आप द्रव्यमान को परमाणु के "मूल्य" के रूप में और ऊर्जा को किसी प्रकार की मेटा-प्रॉपर्टी के रूप में मान सकते हैं जो परमाणुओं के प्रवाह को निर्धारित करने के लिए कई घटकों द्वारा उपयोग किया जाता है (अर्थात अधिकांश प्रकार के स्विच के संकेत पर निर्भर करते हैं) शक्ति)। (m,E)
जब आवश्यक हो, मैं परमाणुओं को निरूपित करूंगा । कार्यक्रम की शुरुआत में, ग्रिड एक गुच्छा के साथ शुरू होता है(1,0)
आप चार घटकों पर जहां भी जगह रखते हैं वहां से परमाणु UDLR
(जहां अक्षर उस दिशा को इंगित करता है जहां परमाणु शुरू में घूम रहा है)। बोर्ड को तब घटकों के एक पूरे समूह के साथ आबाद किया जाता है जो परमाणुओं के द्रव्यमान और ऊर्जा को बदलते हैं, उनकी दिशा बदलते हैं या अन्य अधिक परिष्कृत चीजें करते हैं। पूरी सूची के लिए एसोलैंग्स पेज देखें , लेकिन मैं उनमें से अधिकांश को इस स्पष्टीकरण में पेश करूंगा। एक अन्य महत्वपूर्ण बिंदु (जो प्रोग्राम कई बार उपयोग करता है) यह है कि ग्रिड टॉरॉयडल है: एक परमाणु जो किसी भी तरफ से टकराता है वह विपरीत दिशा में फिर से दिखाई देता है, उसी दिशा में आगे बढ़ रहा है।
मैंने कई छोटे हिस्सों में कार्यक्रम लिखा और अंत में उन्हें इकट्ठा किया, इसलिए मैं स्पष्टीकरण के माध्यम से जाऊंगा।
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
ऊपरी दाएं कोने में उसके द्रव्यमान (साथ कम कर जाता है _
) बनने के लिए (0,0)
और एक संलयन रिएक्टर के पक्ष में संग्रहित है Y
। यह उस संख्या पर नज़र रखने के लिए है जिसे हम पढ़ रहे हैं - जैसे ही हम संख्याएँ पढ़ेंगे, हम धीरे-धीरे इसे बढ़ाएँगे और गुणा करेंगे।
R
ऊपरी बाएँ कोने में उसके द्रव्यमान का चरित्र कोड करने के लिए सेट हो जाता है 0
(48) के साथ '0
है, तो बड़े पैमाने पर और ऊर्जा के साथ लगा दिया जाता था @
और अंत में बड़े पैमाने पर एक बार के साथ बढ़ती +
देने के लिए (1,48)
। यह तो विकर्ण दर्पण के साथ पुनः निर्देशित किया जाता \
है और /
एक विखंडन रिएक्टर में संग्रहीत करने के लिए। हम 48
ASCII इनपुट को अंकों के वास्तविक मानों में बदलने के लिए घटाव के लिए उपयोग करेंगे । हमें 1
विभाजन से बचने के लिए जन को भी बढ़ाना पड़ा 0
।
- अंत
U
में, निचले बाएं कोने में वह है जो वास्तव में गति में सब कुछ सेट करता है और शुरू में केवल नियंत्रण प्रवाह के लिए उपयोग किया जाता है।
दाएं पर पुनर्निर्देशित होने के बाद, नियंत्रण परमाणु हिट करता है ?
। यह इनपुट घटक है। यह एक चरित्र को पढ़ता है और परमाणु के द्रव्यमान को ASCII मान और ऊर्जा पढ़ने के लिए सेट करता है 0
। यदि हम इसके बजाय ईओएफ को हिट करते हैं, तो ऊर्जा को सेट किया जाएगा 1
।
परमाणु जारी रहता है और फिर हिट होता है %
। यह मिरर स्विच है। गैर-सकारात्मक ऊर्जा के लिए, यह /
दर्पण की तरह काम करता है । लेकिन सकारात्मक ऊर्जा के लिए यह एक काम करता है \
(और 1 से ऊर्जा भी घटाता है)। इसलिए जब हम पात्रों को पढ़ रहे होते हैं, तो परमाणु ऊपर की ओर परावर्तित होगा और हम चरित्र को संसाधित कर सकते हैं। लेकिन जब हम इनपुट के साथ काम करते हैं, तो परमाणु नीचे की ओर परिलक्षित होगा और हम परिणाम को पुनः प्राप्त करने के लिए विभिन्न तर्क लागू कर सकते हैं। FYI करें, विपरीत घटक है &
।
इसलिए हमें अभी के लिए एक परमाणु मिला है। हम प्रत्येक वर्ण के लिए क्या करना चाहते हैं, उसका अंक मान पढ़ना है, उसे हमारे कुल में जोड़ना है और फिर अगले अंक की तैयारी के लिए कुल 10 से भागना है।
चरित्र परमाणु पहले एक डिफ़ॉल्ट (डिफ़ॉल्ट) फ्यूजन रिएक्टर को हिट करता है Y
। यह परमाणु को विभाजित करता है और हम इनपुट घटक में वापस लूप में नियंत्रण परमाणु के रूप में बाईं ओर जाने वाली प्रतिलिपि का उपयोग करते हैं और अगले वर्ण को पढ़ते हैं। राइट-गोइंग कॉपी पर कार्रवाई की जाएगी। उस मामले पर विचार करें जहां हमने चरित्र पढ़ा है 3
। हमारा परमाणु होगा (51,0)
। हम द्रव्यमान और ऊर्जा को स्वैप करते हैं @
, जैसे कि हम अगले विखंडन रिएक्टर के घटाव का उपयोग कर सकते हैं। रिएक्टर 48
ऊर्जा (द्रव्यमान को बदले बिना) को घटाता है, इसलिए यह दो प्रतियों को भेजता है (0,3)
- ऊर्जा अब हमारे द्वारा पढ़े गए अंक से मेल खाती है। ऊपर जाने वाली प्रतिलिपि के साथ बस छोड़ दिया जाता है ;
(एक घटक जो बस आने वाले सभी परमाणुओं को नष्ट कर देता है)। हम नीचे की प्रतिलिपि के साथ काम करते रहेंगे। आपको इसके रास्ते का अनुसरण करना होगा/
और \
थोड़ा सा दर्पण।
@
बस से पहले संलयन रिएक्टर फिर से बड़े पैमाने पर और ऊर्जा अदला-बदली, ऐसा है कि हम जोड़ देंगे (3,0)
में हमारे कुल चल रहा है Y
। ध्यान दें कि चल रहे कुल में हमेशा 0
ऊर्जा होगी।
अब J
एक छलांग है। यह क्या करता है किसी भी आने वाली परमाणु को अपनी ऊर्जा से आगे कूदना है। यदि यह है 0
, तो परमाणु बस सीधा चलता रहता है। यदि यह है तो यह 1
एक सेल को छोड़ देगा, अगर यह 2
दो सेल को छोड़ देगा और इसी तरह। ऊर्जा छलांग में खर्च होती है, इसलिए परमाणु हमेशा ऊर्जा के साथ समाप्त होता है 0
। चूंकि रनिंग टोटल में शून्य ऊर्जा होती है, इसलिए अभी के लिए जंप को अनदेखा किया जाता है और परमाणु को फ्यूजन रिएक्टर में पुनर्निर्देशित किया जाता है {
जो इसके द्रव्यमान को गुणा करता है 10
। डाउनिंग कॉपी को छोड़ दिया जाता है, ;
जबकि ऊपर जाने वाली कॉपी को Y
नए चलन के रूप में रिएक्टर में वापस भेज दिया जाता है।
जब तक हम ईओएफ को हिट नहीं करते, तब तक उपरोक्त दोहराता रहता है (एक मजाकिया रूप से पाइपलाइज्ड तरीके से जहां नए अंकों को पिछले वाले से पहले संसाधित किया जाता है)। अब %
परमाणु को नीचे की ओर भेजेंगे। (0,1)
चल रहे कुल रिएक्टर को मारने से पहले इस परमाणु को अब चालू करने का विचार है ताकि (क) कुल प्रभावित न हो (शून्य द्रव्यमान) और बी) हमें 1
ऊपर कूदने की ऊर्जा मिलती है [
। हम आसानी से ऊर्जा का ध्यान रख सकते हैं $
, जिससे ऊर्जा बढ़ती है।
मुद्दा यह है कि ?
जब आप ईओएफ को मार रहे हैं तो द्रव्यमान को रीसेट नहीं किया जाता है, इसलिए द्रव्यमान अभी भी पिछले चरित्र को पढ़ा जाएगा, और ऊर्जा होगी 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
प्लसस के साथ एक 10 देता है जिसे हम क्लोन करते हैं और एक विखंडन और एक फ्यूजन रिएक्टर में फ़ीड करते हैं ताकि हम 10. से विभाजित और गुणा कर सकें। लूप अनिवार्य रूप [
से शीर्ष कोने में शुरू होता है । वर्तमान मूल्य विभाजित है: एक प्रति को 10 से विभाजित किया जाता है, फिर 10 से गुणा किया जाता है और एक विखंडन रिएक्टर में संग्रहीत किया जाता है, जो तब शीर्ष पर दूसरी प्रति से मारा जाता है। यह गणना i % 10
करता है i - ((i/10) * 10)
। ध्यान दें कि A
विभाजन के बाद और गुणा से पहले मध्यवर्ती परिणाम को विभाजित करता है, जैसे कि हम i / 10
अगले पुनरावृत्ति में फ़ीड कर सकते हैं ।
%
पाश aborts एक बार यात्रा चर 0. हिट के बाद से इस और अधिक या कम एक do-जबकि पाश है, इस कोड को भी मुद्रण के लिए काम करेगा 0
(अग्रणी शून्य अन्यथा बनाने के बिना)। एक बार जब हम लूप छोड़ देते हैं तो हम स्टैक को खाली करना चाहते हैं और अंकों को प्रिंट करते हैं। S
के विपरीत है Z
, इसलिए यह एक स्विच है जो आने वाली परमाणु को गैर-सकारात्मक ऊर्जा के साथ 90 डिग्री दाईं ओर विक्षेपित करेगा। इसलिए परमाणु वास्तव में एक अंक को पॉप S
करने के K
लिए सीधे से किनारे पर चला जाता है (ध्यान दें ~
कि यह सुनिश्चित करता है कि आने वाले परमाणु में ऊर्जा है -1
)। 48
संबंधित अंकों के ASCII कोड को प्राप्त करने के लिए उस अंक को बढ़ाया जाता है। A
विभाजन अंक के साथ एक प्रति प्रिंट!
और Y
अगले अंक के लिए रिएक्टर में वापस दूसरी प्रति फ़ीड करें । जो कॉपी छपी है उसका उपयोग स्टैक के लिए अगले ट्रिगर के रूप में किया जाता है (ध्यान दें कि दर्पण इसे M
बाईं ओर से हिट करने के लिए किनारे के आसपास भी भेजते हैं )।
जब स्टैक खाली होता है, तो K
परमाणु को प्रतिबिंबित करेगा और अपनी ऊर्जा को +1
इस तरह से मोड़ देगा , जैसे कि यह सीधे से गुजरता है S
। N
एक नई रेखा प्रिंट करता है (सिर्फ इसलिए कि यह साफ है :))। और फिर परमाणु थिरुघ में R'0
फिर से समाप्त हो जाता है Y
। चूंकि आस-पास कोई और परमाणु नहीं हैं, इसलिए इसे कभी जारी नहीं किया जाएगा और कार्यक्रम समाप्त हो जाएगा।
विखंडन संख्या की गणना: रूपरेखा
आइए कार्यक्रम के वास्तविक मांस पर जाएं। कोड मूल रूप से मेरे गणितज्ञ संदर्भ कार्यान्वयन का एक बंदरगाह है:
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
ही काम करती है , जैसे फीफो के आदेश में।)
यहाँ इस अवधारणा के लिए एक रूपरेखा है:
+--- 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
।
कम्प्यूटिंग संख्या: लूप बॉडी
तो जो कुछ बचा है वह दो वर्गों की गणना 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
एस भी इसका हिस्सा हैं) और नीचे के चारों ओर एक पथ (जो 7
एस के माध्यम से जाता है )। कुछ नस्लीय दौड़ की स्थिति से निपटने के लिए मुझे इन्हें जोड़ना पड़ा। विखंडन एक देरी घटक का उपयोग कर सकता है ...
कोड है कि नई सीमा से उत्पन्न करता है 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̠̠͎̺͜ ͚̬̮f̟͞u an͍ ̜̠̙t̸̳̩̝o ̫͉̙͠p̯̱̭͙̜͙͞ŕ̮͓̜o̢̙̣̭g̩̼̣̝r̤͍͔̘̟ͅa̪̜͇m̳̭͔̤̞ͅ ai͜n̳̯̗̳͇̹.