मिनी-फ्लैक, 6851113 चक्र
कार्यक्रम (शाब्दिक)
मैं जानता हूं कि ज्यादातर लोग मिनी-फ्लैक क्वीन की अपेक्षा नहीं कर सकते हैं कि वे अनपेक्षित वर्णों और यहां तक कि मल्टी-बाइट पात्रों का उपयोग कर सकें (एन्कोडिंग को प्रासंगिक बना सकते हैं)। हालाँकि, यह क्वीन करता है, और unprintables, क्वीन के आकार (93919 वर्ण यूटीएफ -8 के 102646 बाइट्स के रूप में एन्कोडेड) के साथ संयुक्त, इस पोस्ट में कार्यक्रम को जगह देना काफी मुश्किल बना देता है।
हालांकि, कार्यक्रम बहुत दोहरावदार है, और इस तरह, वास्तव में अच्छी तरह से संपीड़ित करता है । ताकि पूरे कार्यक्रम को स्टैक एक्सचेंज से शाब्दिक रूप से उपलब्ध हो, नीचे दिए गए संक्षिप्त के पीछे छिपे हुए पूर्ण क्वीन के -compressed संस्करण का एक xxd
प्रतिवर्ती हेक्सडंप है gzip
:
00000000: 1f8b 0808 bea3 045c 0203 7175 696e 652e .......\..quine.
00000010: 6d69 6e69 666c 616b 00ed d9db 6a13 4118 miniflak....j.A.
00000020: 0060 2f8b f808 0d64 a1c1 1dc8 4202 c973 .`/....d....B..s
00000030: 4829 4524 0409 22e2 5529 a194 1242 1129 H)E$..".U)...B.)
00000040: d2d7 ca93 f9cf 4c4c d45b 9536 e6db 6967 ......LL.[.6..ig
00000050: 770e 3bc9 ffed eca9 edb7 b1a4 9ad2 6a1d w.;...........j.
00000060: bfab 75db c6c6 6c5f 3d4f a5a6 8da6 dcd8 ..u...l_=O......
00000070: 465b d4a5 5a28 4bd9 719d 727b aa79 f9c9 F[..Z(K.q.r{.y..
00000080: 43b6 b9d7 8b17 cd45 7f79 d3f4 fb65 7519 C......E.y...eu.
00000090: 59ac 9a65 bfdf 8f86 e6b2 69a2 bc5c 4675 Y..e......i..\Fu
000000a0: d4e4 bcd9 5637 17b9 7099 9b73 7dd3 fcb2 ....V7..p..s}...
000000b0: 4773 b9bc e9bd b9ba 3eed 9df7 aeaf 229d Gs......>.....".
000000c0: e6ed 5eae 3aef 9d46 21b2 5e4d bd28 942e ..^.:..F!.^M.(..
000000d0: 6917 d71f a6bf 348c 819f 6260 dfd9 77fe i.....4...b`..w.
000000e0: df86 3e84 74e4 e19b b70e 9af0 111c fa0d ..>.t...........
000000f0: d29c 75ab 21e3 71d7 77f6 9d8f f902 6db2 ..u.!.q.w.....m.
00000100: b8e1 0adf e9e0 9009 1f81 f011 18d8 1b33 ...............3
00000110: 72af 762e aac2 4760 6003 1bd8 698c c043 r.v...G``...i..C
00000120: 8879 6bde 9245 207c 04ae 5ce6 2d02 e1bb .yk..E |..\.-...
00000130: 7291 4540 57f8 fe0d 6546 f89b a70b 8da9 r.E@W...eF......
00000140: f5e7 03ff 8b8f 3ad6 a367 d60b f980 679d ......:..g....g.
00000150: d3d6 1c16 f2ff a767 e608 57c8 c27d c697 .......g..W..}..
00000160: 4207 c140 9e47 9d57 2e50 6e8e c215 b270 B..@.G.W.Pn....p
00000170: bdf6 9926 9e47 9d05 ce02 0ff0 5ea7 109a ...&.G......^...
00000180: 8ba6 b5db 880b 970b 9749 2864 47d8 1b92 .........I(dG...
00000190: 39e7 9aec 8f0e 9e93 117a 6773 b710 ae53 9........zgs...S
000001a0: cd01 17ee b30e d9c1 15e6 6186 7a5c dc26 ..........a.z\.&
000001b0: 9750 1d51 610a d594 10ea f3be 4b7a 2c37 .P.Qa.......Kz,7
000001c0: 2f85 7a14 8fc4 a696 304d 4bdf c143 8db3 /.z.....0MK..C..
000001d0: d785 8a96 3085 2acc 274a a358 c635 8d37 ....0.*.'J.X.5.7
000001e0: 5f37 0f25 8ff5 6854 4a1f f6ad 1fc7 dbba _7.%..hTJ.......
000001f0: 51ed 517b 8da2 4b34 8d77 e5b2 ec46 7a18 Q.Q{..K4.w...Fz.
00000200: ffe8 3ade 6fed b2f2 99a3 bae3 c949 9ab5 ..:.o........I..
00000210: ab75 d897 d53c b258 a555 1b07 63d6 a679 .u...<.X.U..c..y
00000220: 4a51 5ead a23a 6a72 9eb6 d569 960b f3dc JQ^..:jr...i....
00000230: 9ceb 53fa 658f 345f ad07 6f6f efce 06ef ..S.e.4_..oo....
00000240: 0677 b791 cef2 f620 57bd 1b9c 4521 b241 .w..... W...E!.A
00000250: 4d83 2894 2eaf a140 8102 050a 1428 50a0 M.(....@.....(P.
00000260: 4081 0205 0a14 2850 a040 8102 050a 1428 @.....(P.@.....(
00000270: 50a0 4081 0205 0a14 2850 a040 8102 050a P.@.....(P.@....
00000280: 1428 50a0 4081 0205 0a14 2850 a040 8102 .(P.@.....(P.@..
00000290: 050a 1428 50a0 4081 0205 0a14 2850 a040 ...(P.@.....(P.@
000002a0: 8102 050a 1428 50a0 4081 0205 0a14 2850 .....(P.@.....(P
000002b0: a040 8102 050a 1428 50a0 4081 0205 0a14 .@.....(P.@.....
000002c0: 2850 a040 8102 050a 1428 50a0 4081 0205 (P.@.....(P.@...
000002d0: 0a14 2850 a040 8102 050a 1428 50a0 4081 ..(P.@.....(P.@.
000002e0: 0205 0a14 2850 a040 8102 050a 1428 50a0 ....(P.@.....(P.
000002f0: 4081 0205 0a14 2850 a040 8102 050a 1428 @.....(P.@.....(
00000300: 50a0 4081 0205 0a14 2850 a040 8102 050a P.@.....(P.@....
00000310: 1428 50a0 4081 0205 0a14 2850 a040 8102 .(P.@.....(P.@..
00000320: 050a 1428 50a0 4081 0205 0a14 2850 a040 ...(P.@.....(P.@
00000330: 8102 050a 1428 50a0 4081 0205 0a14 2850 .....(P.@.....(P
00000340: a040 8102 050a 1428 50a0 4081 0205 0a14 .@.....(P.@.....
00000350: 2850 a040 8102 050a 1428 50a0 4081 0205 (P.@.....(P.@...
00000360: 0a14 2850 a040 8102 050a 1428 50a0 4081 ..(P.@.....(P.@.
00000370: 0205 0a14 2850 a01c 14ca 7012 cbb4 a6e9 ....(P....p.....
00000380: e6db e6b1 e4b1 9e4c 4ae9 d3be f5f3 745b .......LJ.....t[
00000390: 37a9 3d6a af49 7489 a6e9 ae5c 96dd 488f 7.=j.It....\..H.
000003a0: d31f 5da7 fbad 5d56 3e73 5277 7cf5 aa7b ..]...]V>sRw|..{
000003b0: 3fbc df7c e986 c3ba 5ee4 3c6f 74f7 c3e1 ?..|....^.<ot...
000003c0: 301a bb45 d795 9afb fbdc 1495 65d5 6d9b 0..E........e.m.
000003d0: baf7 a5b4 a87d 4a5b d7fd b667 b788 ec27 .....}J[...g...'
000003e0: c5d8 28bc b96a 9eda 7a50 524d 290a a5cb ..(..j..zPRM)...
000003f0: cbef 38cb c3ad f690 0100 ..8.......
(हां, यह इतना दोहराव है कि आप संपीड़ित होने के बाद भी दोहराव देख सकते हैं )।
प्रश्न कहता है "मैं TIO में आपके प्रोग्राम को नहीं चलाने की अत्यधिक अनुशंसा करूंगा। न केवल डेस्कटॉप दुभाषिया की तुलना में TIO धीमा है, बल्कि लगभग एक मिनट में टाइमआउट भी होगा। यह बेहद प्रभावशाली होगा यदि कोई व्यक्ति रन बनाने में काफी कम स्कोर करता है। इससे पहले कि TIO का कार्यक्रम समाप्त हो जाए। " मैं ऐसा कर सकता हूँ! रूबी दुभाषिया का उपयोग करते हुए, TIO पर चलने में लगभग 20 सेकंड लगते हैं: इसे ऑनलाइन आज़माएं!
कार्यक्रम (आसानी से)
अब मैंने प्रोग्राम का एक संस्करण दिया है जिसे कंप्यूटर पढ़ सकते हैं, आइए एक ऐसे संस्करण की कोशिश करें जिसे मनुष्य पढ़ सकते हैं। मैंने उन बाइट्स को परिवर्तित किया है जो क्वीन को कोडपेज 437 (यदि उनके पास उच्च बिट सेट है) या यूनिकोड नियंत्रण चित्रों (यदि वे एएससीआईआई नियंत्रण कोड हैं) में बदल दिया है, तो व्हाट्सएप (किसी भी पूर्व-मौजूदा व्हाट्सएप को चित्रों को नियंत्रित करने के लिए परिवर्तित किया गया था) ), रन-लेंथ-एन्कोडेड सिंटैक्स का उपयोग कर «string×length»
, और कुछ डेटा-हैवी बिट्स:
␠
(((()()()()){}))
{{}
(({})[(()()()())])
(({})(
{{}{}((()[()]))}{}
(((((((({})){}){}{})){}{}){}){}())
{
({}(
(␀␀!S␠su! … many more comment characters … oq␝qoqoq)
(«()×35» («()×44» («()×44» («()×44» («()×44» («()×45»
… much more data encoded the same way …
(«()×117»(«()×115»(«()×117»
«000010101011┬â┬ … many more comment characters … ┬â0┬â┬à00␈␈
)[({})(
([({})]({}{}))
{
((()[()]))
}{}
{
{
({}(((({}())[()])))[{}()])
}{}
(({}))
((()[()]))
}{}
)]{}
%Wwy$%Y%ywywy$wy$%%%WwyY%$$wy%$$%$%$%$%%wy%ywywy'×almost 241»
,444454545455┬ç┬ … many more comment characters … -a--┬ü␡┬ü-a␡┬ü
)[{}()])
}{}
{}({}())
)[{}])
(({})(()()()()){})
}{}{}␊
("लगभग 241" इसलिए है क्योंकि 241 वीं प्रति अनुगामी को याद कर रही है '
, लेकिन अन्यथा अन्य 240 के समान है।)
व्याख्या
टिप्पणियों के बारे में
समझाने वाली पहली बात यह है कि मिनी-फ्लैक कमांड नहीं है जो गैर-वर्णों और अन्य कबाड़ के साथ है? आप सोच सकते हैं कि केवल क्वीन में टिप्पणी जोड़ने से चीजें कठिन हो जाती हैं, लेकिन यह एक गति प्रतियोगिता (आकार प्रतियोगिता नहीं) है, जिसका अर्थ है कि टिप्पणियां कार्यक्रम की गति को चोट नहीं पहुंचाती हैं। इस बीच, ब्रेन-फ्लैक, और इस प्रकार मिनी-फ्लैक, बस स्टैक की सामग्री को मानक आउटपुट में डंप कर देता है; यदि आपको यह सुनिश्चित करना है कि स्टैक केवल निहित हैआपके प्रोग्राम की कमांड बनाने वाले पात्रों को, आपको स्टैक की सफाई के लिए चक्र खर्च करने होंगे। जैसा कि यह है, ब्रेन-फ्लैक अधिकांश पात्रों को अनदेखा करता है, इसलिए जब तक हम यह सुनिश्चित करते हैं कि जंक स्टैक तत्व ब्रेन-फ्लैक कमांड (इसे ब्रेन-फ्लैक / मिनी-फ्लैक पॉलीग्लॉट बनाते हैं) मान्य नहीं हैं, और नकारात्मक या बाहर नहीं हैं यूनिकोड श्रेणी, हम उन्हें केवल स्टैक पर छोड़ सकते हैं, उन्हें आउटपुट करने की अनुमति दे सकते हैं, और हमारे कार्यक्रम में उसी गुण को एक ही स्थान पर रख सकते हैं ताकि वह संपत्ति को बनाए रख सके।
इसका एक विशेष रूप से महत्वपूर्ण तरीका है जिसका हम लाभ उठा सकते हैं। क्वीन एक लंबी डेटा स्ट्रिंग का उपयोग करके काम करता है, और मूल रूप से क्वीन से सभी आउटपुट डेटा स्ट्रिंग को विभिन्न तरीकों से प्रारूपित करके निर्मित किया जाता है। केवल एक डेटा स्ट्रिंग है, इस तथ्य के बावजूद कि कार्यक्रम में कई टुकड़े हैं; इसलिए हमें प्रोग्राम के विभिन्न हिस्सों को प्रिंट करने के लिए एक ही डेटा स्ट्रिंग का उपयोग करने में सक्षम होना चाहिए। "जंक डेटा कोई फर्क नहीं पड़ता" चाल हमें बहुत सरल तरीके से ऐसा करने देती है; हम उन वर्णों को संग्रहीत करते हैं जो डेटा स्ट्रिंग में प्रोग्राम जोड़ते हैं या उनके ASCII कोड से मान जोड़ते या घटाते हैं। विशेष रूप से, प्रोग्राम की शुरुआत करने वाले पात्रों को उनके ASCII कोड + 4 के रूप में संग्रहीत किया जाता है, जो अक्षर उस अनुभाग को बनाते हैं जो उनके ASCII कोड - 4 के रूप में लगभग 241 बार दोहराया जाता है;ऑफ़सेट के साथ डेटा स्ट्रिंग का प्रत्येक वर्ण; यदि, उदाहरण के लिए, हम इसे प्रत्येक वर्ण कोड में 4 जोड़कर प्रिंट करते हैं, तो हमें दोहराया अनुभाग का एक दोहराव मिलता है, कुछ टिप्पणियों के साथ पहले और बाद में। (वे टिप्पणियाँ केवल कार्यक्रम के अन्य खंड हैं, जिसमें चरित्र कोड शिफ्ट किए गए हैं ताकि वे कोई मान्य ब्रेन-फ्लैक कमांड न बनाएं, क्योंकि गलत ऑफसेट जोड़ा गया था। हमें ब्रेन-फ्लाक कमांड को चकमा देना है, न कि केवल मिनी- फ्लैक कमांड, प्रश्न के प्रतिबंधित-स्रोत भाग का उल्लंघन करने से बचने के लिए, यह सुनिश्चित करने के लिए ऑफ़सेट का विकल्प तैयार किया गया था।)
इस टिप्पणी चाल के कारण, हमें वास्तव में केवल दो अलग-अलग तरीकों से स्वरूपित डेटा स्ट्रिंग को आउटपुट करने में सक्षम होने की आवश्यकता है: ए) स्रोत के रूप में उसी तरह एन्कोड किया गया, बी) वर्ण कोड के साथ प्रत्येक कोड में निर्दिष्ट ऑफसेट के साथ। यह एक विशाल सरलीकरण है जो अतिरिक्त लंबाई को पूरी तरह से इसके लायक बनाता है।
कार्यक्रम की संरचना
इस प्रोग्राम में चार भाग होते हैं: इंट्रो, डेटा स्ट्रिंग, डेटा स्ट्रिंग फ़ॉर्मेटर और आउट्रो। इंट्रो और आउट्रो मूल रूप से डेटा स्ट्रिंग और उसके फ़ॉर्मेटर को लूप में चलाने के लिए जिम्मेदार होते हैं, जो हर बार उपयुक्त प्रारूप निर्दिष्ट करते हैं (अर्थात एन्कोड या ऑफ़सेट करना है, और ऑफ़सेट का उपयोग करना है)। डेटा स्ट्रिंग सिर्फ डेटा है, और क्वीन का एकमात्र हिस्सा है जिसके लिए इसे बनाने वाले वर्ण डेटा स्ट्रिंग में शाब्दिक रूप से निर्दिष्ट नहीं हैं (ऐसा करना स्पष्ट रूप से असंभव होगा, क्योंकि यह खुद से अधिक लंबा होगा); यह इस तरह से लिखा गया है कि विशेष रूप से खुद को पुन: उत्पन्न करना आसान है। डेटा स्ट्रिंग फॉर्मैटर 241 लगभग समान भागों से बना है, जिनमें से प्रत्येक डेटा स्ट्रिंग में 241 में से एक विशिष्ट डेटा प्रारूपित करता है।
कार्यक्रम के प्रत्येक भाग को डेटा स्ट्रिंग और उसके फॉर्मेटर के माध्यम से उत्पादित किया जा सकता है:
- आउटरो का उत्पादन करने के लिए, ऑफसेट +8 के साथ डेटा स्ट्रिंग को प्रारूपित करें
- डेटा स्ट्रिंग फॉर्मेटर का उत्पादन करने के लिए, ऑफसेट +4, 241 बार के साथ डेटा स्ट्रिंग को प्रारूपित करें
- डेटा स्ट्रिंग का उत्पादन करने के लिए, डेटा स्ट्रिंग को स्रोत प्रारूप में एन्कोडिंग के माध्यम से प्रारूपित करें
- परिचय का उत्पादन करने के लिए, ऑफसेट -4 के साथ डेटा स्ट्रिंग को प्रारूपित करें
इसलिए हमें केवल यह देखना है कि कार्यक्रम के ये भाग कैसे काम करते हैं।
डेटा स्ट्रिंग
(«()×35» («()×44» («()×44» («()×44» («()×44» («()×45» …
हमें डेटा स्ट्रिंग के लिए एक सरल एन्कोडिंग की आवश्यकता है क्योंकि हमें मिनी-फ्लैक कोड में एन्कोडिंग को उलटने में सक्षम होना चाहिए। आप इससे ज्यादा सरल नहीं हो सकते!
इस क्वीन के पीछे महत्वपूर्ण विचार (टिप्पणी की चाल के अलावा) यह ध्यान रखना है कि मूल रूप से केवल एक ही जगह है जहां हम बड़ी मात्रा में डेटा स्टोर कर सकते हैं: प्रोग्राम स्रोत के विभिन्न घोंसले के स्तर के भीतर "कमांड रिटर्न मान"। (यह आमतौर पर तीसरे स्टैक के रूप में जाना जाता है, हालांकि मिनी-फ्लैक में दूसरा स्टैक नहीं है, इसलिए "वर्किंग स्टैक" मिनी-फ्लैक संदर्भ में बेहतर नाम है।) डेटा संग्रहीत करने के लिए अन्य संभावनाएं मुख्य / पहला स्टैक होगा (जो काम नहीं करता है)। क्योंकि जहां हमारा आउटपुट जाना है, और हम आउटपुट को स्टोरेज को दूर से कुशल तरीके से आगे नहीं बढ़ा सकते हैं), और एक सिंगल स्टैक एलिमेंट (जो इस समस्या के लिए अनुपयुक्त है, क्योंकि यह घातीय समय लगता है, में एक बायग्नम में इनकोड किया गया है) इससे डेटा निकालें); जब आप उन्हें समाप्त करते हैं, तो काम करने वाला स्टैक एकमात्र शेष स्थान होता है।
इस स्टैक पर डेटा को "स्टोर" करने के लिए, हम असंतुलित कमांड का उपयोग करते हैं (इस मामले में, (…)
कमांड का पहला भाग ), जो बाद में डेटा स्ट्रिंग फॉर्मैटर के भीतर संतुलित होगा। हर बार जब हम फ़ॉर्मेटर के भीतर इनमें से किसी एक कमांड को बंद करते हैं, तो यह डेटा स्ट्रिंग से लिए गए डेटम के योग को धकेलता है, और फॉर्मेटर के भीतर उस घोंसले के स्तर पर सभी कमांड के रिटर्न मान; हम यह सुनिश्चित कर सकते हैं कि उत्तरार्द्ध शून्य में जोड़ें, इसलिए फ़ॉर्मेटर डेटा स्ट्रिंग से लिए गए एकल मानों को देखता है।
: प्रारूप बहुत सरल है (
के द्वारा पीछा किया, एन की प्रतियां ()
, जहां n संख्या हम दुकान करना चाहते हैं। (ध्यान दें कि इसका मतलब है कि हम केवल गैर-नकारात्मक संख्याओं को संग्रहीत कर सकते हैं, और डेटा स्ट्रिंग के अंतिम तत्व को सकारात्मक होना चाहिए।)
डेटा स्ट्रिंग के बारे में एक छोटा सा अनपेक्षित बिंदु जो यह क्रम में है। डेटा स्ट्रिंग का "प्रारंभ" अंत है कार्यक्रम की शुरुआत, यानी सबसे बाहरी घोंसला स्तर; यह भाग अंतिम रूप में स्वरूपित हो जाता है (जैसा कि सूत्र अंतरतम से बाह्यतम घोंसले के स्तर तक चलता है)। हालांकि, अंतिम स्वरूपित होने के बावजूद, यह पहले मुद्रित हो जाता है , क्योंकि स्टैक पर धकेल दिए गए मानों को मिनी-फ्लैक दुभाषिया द्वारा अंतिम रूप से मुद्रित किया जाता है। एक ही सिद्धांत पूरे कार्यक्रम के लिए लागू होता है; हमें पहले आउटरो को प्रारूपित करने की आवश्यकता है, फिर डेटा स्ट्रिंग फ़ॉर्मेटर, फिर डेटा स्ट्रिंग, फिर इंट्रो, यानी उस क्रम के रिवर्स जिसमें वे प्रोग्राम में संग्रहीत हैं।
डेटा स्ट्रिंग फ़ॉर्मेटर
)[({})(
([({})]({}{}))
{
((()[()]))
}{}
{
{
({}(((({}())[()])))[{}()])
}{}
(({}))
((()[()]))
}{}
)]{}
डेटा स्ट्रिंग फॉर्मैटर 241 खंडों से बना होता है, जिनमें से प्रत्येक में समान कोड होता है (एक खंड में थोड़ी भिन्न टिप्पणी होती है), जिनमें से प्रत्येक डेटा स्ट्रिंग के एक विशिष्ट वर्ण को प्रारूपित करता है। (हम यहां एक लूप का उपयोग नहीं कर सकते हैं: हमें असंतुलित )
मिलान के माध्यम से डेटा स्ट्रिंग को पढ़ने के लिए एक असंतुलित की आवश्यकता है (
, और हम उन में से एक को {…}
लूप के अंदर नहीं डाल सकते हैं , लूप का एकमात्र रूप मौजूद है। इसलिए इसके बजाय, हम " "फ़ॉर्मेटर" को अनियंत्रित करें, और फॉर्मेट की ऑफसेट 241 बार के साथ डेटा स्ट्रिंग को आउटपुट करने के लिए बस इंट्रो / आउट्रो प्राप्त करें।)
)[({})( … )]{}
फॉर्मेटर तत्व का बाहरी भाग डेटा स्ट्रिंग के एक तत्व को पढ़ता है; डेटा स्ट्रिंग की एन्कोडिंग की सादगी इसे पढ़ने में थोड़ी जटिलता की ओर ले जाती है। हम (…)
डेटा स्ट्रिंग में बेजोड़ को बंद करके शुरू करते हैं , फिर […]
दो मानों को नकारें ( ): डेटा स्ट्रिंग ( ({})
) और बाकी प्रोग्राम के रिटर्न वैल्यू से जो डेटा हम पढ़ते हैं । हम फॉर्मेटर तत्व के बाकी के रिटर्न मान को कॉपी करते हैं (…)
और कॉपी को नकारात्मक संस्करण के साथ जोड़ते हैं {}
। अंतिम परिणाम यह है कि डेटा स्ट्रिंग तत्व और फॉर्मैटर तत्व का एक साथ रिटर्न वैल्यू डेटम माइनस है जिसमें डेटम माइनस रिटर्न वैल्यू और रिटर्न वैल्यू या 0 है; यह अगले डेटा स्ट्रिंग तत्व को सही मान बनाने के लिए आवश्यक है।
([({})]({}{}))
फ़ॉर्मेटर शीर्ष स्टैक तत्व का उपयोग यह जानने के लिए करता है कि यह किस मोड में है (डेटा स्ट्रिंग स्वरूपण में 0 = प्रारूप, किसी भी अन्य मूल्य = आउटपुट के साथ ऑफसेट)। हालाँकि, डेटा स्ट्रिंग को पढ़ने के बाद, स्टैक पर प्रारूप के शीर्ष पर डेटम है, और हम उन्हें दूसरे तरीके से चाहते हैं। इस कोड को ब्रेन-आलोचना स्वैप कोड का एक छोटा संस्करण है, ले जा रहा है एक के ऊपर ख को ख ऊपर एक + ख ; न केवल यह कम है, यह अधिक उपयोगी (इस विशिष्ट मामले में) भी है, क्योंकि जोड़ने के पक्ष प्रभाव ख के लिए एक जब समस्याग्रस्त नहीं है ख 0 है, और जब ख 0 नहीं है, यह हमारे लिए ऑफसेट गणना करता है।
{
((()[()]))
}{}
{
…
((()[()]))
}{}
ब्रेन-फ्लैक में केवल एक नियंत्रण प्रवाह संरचना है, इसलिए यदि हम while
लूप के अलावा कुछ भी चाहते हैं, तो यह थोड़ा काम करेगा। यह एक "नकारात्मक" संरचना है; यदि स्टैक के शीर्ष पर 0 है, तो यह इसे हटा देता है, अन्यथा यह स्टैक के शीर्ष पर 0 रखता है। (यह बहुत सरलता से काम करता है: जब तक स्टैक के शीर्ष पर 0 नहीं होता है, तब तक स्टैक 1 - 1 को दो बार धक्का दें; जब आप काम कर लें, तो शीर्ष स्टैक तत्व पॉप करें।)
कोड को एक नकारात्मक संरचना के अंदर रखना संभव है, जैसा कि यहां देखा गया है। कोड केवल तभी चलेगा जब स्टैक के ऊपर नॉनज़रो था; इसलिए अगर हमारे पास दो नकारात्मक संरचनाएं हैं, तो यह मानते हुए कि शीर्ष दो स्टैक तत्व दोनों शून्य नहीं हैं , वे एक दूसरे को रद्द कर देंगे, लेकिन पहली संरचना के अंदर कोई भी कोड केवल तभी चलेगा जब शीर्ष स्टैक तत्व नॉनजरो था, और अंदर कोड दूसरी संरचना केवल तभी चलेगी जब शीर्ष स्टैक तत्व शून्य था। दूसरे शब्दों में, यह एक तत्कालीन कथन के बराबर है।
"फिर" क्लॉज में, जो अगर रन नॉनजरो है, तो वास्तव में हमें कुछ नहीं करना है; हम जो चाहते हैं, वह डेटा + ऑफसेट को मुख्य स्टैक पर ले जाना है (ताकि प्रोग्राम के अंत में इसे आउटपुट किया जा सके), लेकिन यह पहले से ही है। इसलिए हमें केवल डेटा स्ट्रिंग तत्व को स्रोत रूप में एन्कोडिंग के मामले से निपटना होगा।
{
({}(((({}())[()])))[{}()])
}{}
(({}))
यहाँ है कि हम ऐसा कैसे करते हैं। {({}( … )[{}()])}{}
संरचना जो काम कर ढेर करने के लिए लूप काउंटर चलती है और यह वहाँ पकड़ कर काम करता है पुनरावृत्तियों की एक विशिष्ट संख्या (के साथ एक पाश के रूप में परिचित होना चाहिए, क्योंकि काम कर ढेर करने के लिए उपयोग से जुड़ा हुआ है यह किसी भी अन्य कोड से सुरक्षित हो जाएगा कार्यक्रम का घोंसला स्तर)। लूप का शरीर है ((({}())[()]))
, जो शीर्ष स्टैक तत्व की तीन प्रतियां बनाता है और 1 को सबसे कम जोड़ता है। दूसरे शब्दों में, यह 41 से ऊपर 40 से ऊपर 40 में ढेर, के शीर्ष पर एक 40 बदल देती है या ASCII, के रूप में देखा (
में (()
; इस बार-बार चल कर देगा (
में (()
में (()()
में (()()()
और इतने पर, और इस प्रकार हमारे डेटा स्ट्रिंग उत्पन्न करने के लिए एक आसान तरीका है (यह मानते हुए कि वहाँ एक बात यह है कि (
ढेर के शीर्ष पर पहले से ही)।
एक बार जब हम लूप के साथ हो जाते हैं, (({}))
तो स्टैक के शीर्ष को डुप्लिकेट करता है (ताकि यह अब के ((()…
बजाय शुरू हो (()…
। प्रमुख (
का उपयोग डेटा स्ट्रिंग फॉर्मैक्टर की अगली प्रति द्वारा अगले चरित्र को प्रारूपित करने के लिए किया जाएगा। यह इसमें विस्तार करेगा (()(()…
फिर (()()(()…
, और इसी तरह, इसलिए यह (
डेटा स्ट्रिंग में पृथक्करण उत्पन्न करता है )।
%Wwy$%Y%ywywy$wy$%%%WwyY%$$wy%$$%$%$%$%%wy%ywywy'
डेटा स्ट्रिंग फॉर्मैटर में रुचि का एक अंतिम बिट है। ठीक है, इसलिए ज्यादातर यह केवल 4 कोडपॉइंट्स को नीचे की ओर स्थानांतरित करने के लिए है; हालाँकि, अंत में उस एपोस्ट्रोफ जगह से बाहर देख सकते हैं। '
(कोडपॉइंट 39) में बदलाव होगा +
(कोडपॉइंट 43), जो ब्रेन-फ्लैक कमांड नहीं है, इसलिए आपने अनुमान लगाया होगा कि यह किसी अन्य उद्देश्य के लिए है।
इसका कारण यह है क्योंकि डेटा स्ट्रिंग फॉर्मैटर को (
पहले से ही स्टैक पर होने की उम्मीद है (इसमें कहीं भी शाब्दिक 40 नहीं है)। '
वास्तव में ब्लॉक की शुरुआत में है जो डेटा स्ट्रिंग फॉर्मैटर को बनाने के लिए दोहराया जाता है, अंत नहीं, इसलिए डेटा स्ट्रिंग फॉर्मेटर के पात्रों को स्टैक पर धकेल दिया गया है (और कोड डेटा स्ट्रिंग को प्रिंट करने के बारे में आगे बढ़ना है। अपने आप में), आउटरो ने स्टैक के शीर्ष पर 39 को 40 के रूप में समायोजित किया है, इसका उपयोग करने के लिए फॉर्मेटर (इस समय चल रहे फॉर्मेटर नहीं, स्रोत में इसका प्रतिनिधित्व) के लिए तैयार है। इसलिए हमारे पास फॉर्मेटर की "लगभग 241" प्रतियां हैं; पहली प्रति अपने पहले चरित्र को याद कर रही है। और वह चरित्र, एपोस्ट्रोफ, डेटा स्ट्रिंग में केवल तीन वर्णों में से एक है जो कार्यक्रम में कहीं भी मिनी-फ्लैक कोड के अनुरूप नहीं है; यह विशुद्ध रूप से एक निरंतर प्रदान करने की एक विधि के रूप में है।
इंट्रो और आउटरो
(((()()()()){}))
{{}
(({})[(()()()())])
(({})(
{{}{}((()[()]))}{}
(((((((({})){}){}{})){}{}){}){}())
{
({}(
(␀␀!S␠su! … many more comment characters … oq␝qoqoq)
…
)[{}()])
}{}
{}({}())
)[{}])
(({})(()()()()){})
}{}{}␊
इंट्रो और आउट्रो वैचारिक रूप से कार्यक्रम का एक ही हिस्सा हैं; एकमात्र कारण जो हम भेद करते हैं वह यह है कि डेटा स्ट्रिंग से पहले आउट्रो को आउटपुट की आवश्यकता होती है और इसके फॉर्मेटर (ताकि यह उनके बाद प्रिंट करता है), जबकि इंट्रो को उनके बाद आउटपुट होने की आवश्यकता है (उनके पहले मुद्रण)।
(((()()()()){}))
हम स्टैक पर 8 की दो प्रतियां रखकर शुरू करते हैं। यह पहली पुनरावृत्ति के लिए ऑफसेट है। दूसरी प्रति इसलिए है क्योंकि मुख्य लूप की उम्मीद है कि ऑफसेट के ऊपर ढेर के ऊपर एक जंक तत्व हो, परीक्षण से पीछे छोड़ दिया जाए जो यह तय करता है कि मुख्य लूप मौजूद है या नहीं, और इसलिए हमें एक जंक तत्व डालने की जरूरत है ताकि यह वह तत्व नहीं है जो हम वास्तव में चाहते हैं; एक प्रतिलिपि ऐसा करने के लिए सबसे कठिन (इस प्रकार आउटपुट के लिए सबसे तेज़) तरीका है।
संख्या 8 के अन्य प्रतिनिधित्व हैं जो अब इस से अधिक नहीं हैं। हालांकि, सबसे तेज़ कोड के लिए जाते समय, यह निश्चित रूप से सबसे अच्छा विकल्प है। एक बात के लिए, का उपयोग ()()()()
करना, की तुलना में तेज है, (()()){}
क्योंकि दोनों 8 वर्णों के लंबे होने के बावजूद, पूर्व एक चक्र है, क्योंकि (…)
2 चक्रों के रूप में गिना जाता है, लेकिन ()
केवल एक के रूप में। एक चक्र सहेजा जा रहा है एक के लिए एक बहुत बड़ा विचार की तुलना में नगण्य है Quine हालांकि,: (
और )
तुलना में काफी कम कोड पॉइंट्स है {
और }
इसलिए उन पर डेटा टुकड़ा पैदा बहुत तेजी से हो जाएगा (और डेटा टुकड़ा कोड में कम जगह ले जाएगा, भी)।
{{} … }{}{}
मुख्य पाश। यह पुनरावृत्तियों की गणना नहीं करता है (यह एक while
लूप है, लूप नहीं है for
, और बाहर तोड़ने के लिए एक परीक्षण का उपयोग करता है)। एक बार जब यह बाहर निकलता है, तो हम शीर्ष दो स्टैक तत्वों को छोड़ देते हैं; शीर्ष तत्व एक हानिरहित 0 है, लेकिन नीचे का तत्व "अगले पुनरावृत्ति पर उपयोग करने के लिए प्रारूप" होगा, जो (एक नकारात्मक ऑफसेट होने के नाते) एक ऋणात्मक संख्या है, और यदि मिनी पर स्टैक पर कोई नकारात्मक संख्या है, तो -फ्लाक प्रोग्राम से बाहर निकलता है, दुभाषिया उन्हें आउटपुट करने की कोशिश करता है।
क्योंकि यह लूप बाहर तोड़ने के लिए एक स्पष्ट परीक्षण का उपयोग करता है, इसलिए उस परीक्षण का परिणाम स्टैक पर छोड़ दिया जाएगा, इसलिए हम इसे पहली चीज़ के रूप में छोड़ देते हैं जो हम करते हैं (इसका मूल्य उपयोगी नहीं है)।
(({})[(()()()())])
यह कोड स्टैक एलिमेंट f के ऊपर 4 और f - 4 को पुश करता है , जबकि उस एलिमेंट को जगह पर छोड़ता है। हम अग्रिम में अगले पुनरावृत्ति के लिए प्रारूप की गणना कर रहे हैं (जबकि हमारे पास लगातार 4 काम हैं), और साथ ही कार्यक्रम के अगले कुछ हिस्सों के लिए सही क्रम में स्टैक प्राप्त करना है: हम प्रारूप के रूप में f का उपयोग करेंगे। इस पुनरावृत्ति, और इससे पहले 4 की जरूरत है।
(({})( … )[{}])
यह कार्य ढेर पर f - 4 की एक प्रति बचाता है , ताकि हम इसे अगले पुनरावृत्ति के लिए उपयोग कर सकें। ( च का मूल्य अभी भी उस बिंदु पर मौजूद होगा, लेकिन यह स्टैक पर एक अजीब जगह पर होगा, और भले ही हम इसे सही जगह पर पैंतरेबाज़ी कर सकते हैं, हमें इसे से 4 घटाकर चक्र खर्च करना होगा, और उस घटाव को करने के लिए कोड को प्रिंट करना। अब इसे स्टोर करना आसान है।)
{{}{}((()[()]))}{}
यह देखने के लिए एक परीक्षण है कि ऑफसेट 4 है (यानी एफ - 4 0 है)। यदि यह है, तो हम डेटा स्ट्रिंग फॉर्मेटर को प्रिंट कर रहे हैं, इसलिए हमें इस ऑफसेट पर केवल एक बार के बजाय डेटा स्ट्रिंग और इसके फॉर्मेटर को 241 बार चलाने की आवश्यकता है। कोड काफी सरल है: यदि f - 4 नॉनज़ेरो है, तो f - 4 और 4 को शून्य की एक जोड़ी के साथ बदलें ; फिर किसी भी स्थिति में, शीर्ष स्टैक तत्व को पॉप करें। अब हमारे पास स्टैक पर f के ऊपर एक संख्या है , या तो 4 (यदि हम इस पुनरावृत्ति को 241 बार प्रिंट करना चाहते हैं) या 0 (यदि हम इसे केवल एक बार प्रिंट करना चाहते हैं)।
(
((((((({})){}){}{})){}{}){}){}
()
)
यह ब्रेन-फ्लैक / मिनी-फ्लैक निरंतर का एक दिलचस्प प्रकार है; यहां लंबी लाइन 60 नंबर का प्रतिनिधित्व करती है। आप की कमी पर भ्रमित हो सकते हैं ()
, जो सामान्य रूप से ब्रेन-फ्लैक स्थिरांक में सभी जगह हैं; यह एक नियमित संख्या नहीं है, लेकिन एक चर्च अंक है, जो दोहराव के संचालन के रूप में संख्याओं की व्याख्या करता है। उदाहरण के लिए, चर्च संख्या 60 के लिए, यहां देखा गया, इसके इनपुट की 60 प्रतियां बनाता है और उन सभी को एक साथ एक मूल्य में जोड़ता है; ब्रेन-फ्लैक में, केवल एक चीज जिसे हम जोड़ सकते हैं, नियमित संख्याएं हैं, इसके अलावा, इसलिए हम स्टैक के शीर्ष की 60 प्रतियां जोड़ते हैं और इस प्रकार स्टैक के शीर्ष को 60 से गुणा करते हैं।
एक साइड नोट के रूप में, आप एक अंडरलोड अंक खोजक का उपयोग कर सकते हैं , जो कि मिनी-फ्लैक में भी उचित संख्या का पता लगाने के लिए अंडरलोड सिंटैक्स में चर्च अंक उत्पन्न करता है। अंडरलोड अंक (शून्य के अलावा) ऑपरेशन "डुप्लिकेट टॉप स्टैक एलिमेंट" :
और "टॉप टू स्टैक एलिमेंट्स" को मिलाते हैं *
; उन दोनों के संचालन, ब्रेन-आलोचना में मौजूद तो आप बस का अनुवाद :
करने के लिए )
, *
करने के लिए {}
, आगे जोड़ते एक {}
, और काफी जोड़ने के (
संतुलन के लिए शुरू में (यह मुख्य ढेर और काम ढेर के एक अजीब मिश्रण उपयोग कर रहा है, लेकिन यह काम करता है)।
यह विशेष कोड टुकड़ा चर्च के अंक 60 का उपयोग करता है (प्रभावी रूप से "60 से गुणा" स्निपेट), एक वृद्धि के साथ, अभिव्यक्ति 60 x + 1 उत्पन्न करने के लिए । इसलिए यदि हमारे पास पिछले चरण से 4 था, तो यह हमें एक मूल्य देता है। 241 में, या यदि हमारे पास 0 था, तो हमें सिर्फ 1 का मान मिलता है, अर्थात यह सही रूप से हमारे द्वारा पुनरावृत्तियों की संख्या की गणना करता है।
241 का चुनाव संयोग नहीं है; यह एक होने के लिए चुना गया एक मूल्य था) लगभग उस लंबाई जिस पर कार्यक्रम वैसे भी समाप्त हो जाएगा और बी) एक गोल संख्या से 4 गुना अधिक। इस मामले में राउंड नंबर, 60, चर्च अंकों के रूप में कम प्रतिनिधित्व करते हैं क्योंकि आपके पास कॉपी करने के लिए अधिक लचीलापन है। कार्यक्रम में 241 तक की लंबाई लाने के लिए बाद में पैडिंग शामिल है।
{
({}(
…
)[{}()])
}{}
यह लूप के लिए है, जैसा कि पहले देखा गया है, जो कि इसके अंदर कोड को मुख्य स्टैक के शीर्ष के बराबर कई बार चलाता है (जो इसे खपत करता है; लूप काउंटर खुद काम कर रहे स्टैक पर संग्रहीत होता है, लेकिन दृश्यता; यह प्रोग्राम के घोंसले के स्तर से जुड़ा हुआ है और इस प्रकार यह कुछ भी असंभव है, लेकिन लूप के लिए स्वयं इसके साथ बातचीत करने के लिए)। यह वास्तव में 1 या 241 बार डेटा स्ट्रिंग और उसके फॉर्मेटर को चलाता है, और जैसा कि हमने अब उन सभी मूल्यों को पॉपअप किया है जो हम अपने नियंत्रण प्रवाह गणना के लिए मुख्य स्टैक से उपयोग कर रहे थे, हमारे पास इसके शीर्ष पर उपयोग करने के लिए प्रारूप है, जिसके लिए तैयार है उपयोग करने के लिए फ़ॉर्मेटर।
(␀␀!S␠su! … many more comment characters … oq␝qoqoq)
यहाँ टिप्पणी पूरी तरह से ब्याज के बिना नहीं है। एक बात के लिए, ब्रेन-फ्लैक कमांड के एक जोड़े हैं; )
अंत में स्वाभाविक रूप से जिस तरह से कार्यक्रम काम के विभिन्न क्षेत्रों के बीच संक्रमण है, इसलिए का एक पक्ष प्रभाव के रूप में उत्पन्न होता है (
शुरू में मैन्युअल रूप से इसे संतुलित करने के लिए (और टिप्पणी के अंदर की लंबाई के बावजूद जोड़ा गया है, एक टिप्पणी के अंदर डाल एक ()
कमांड अभी भी एक ()
कमांड है, इसलिए यह सब डेटा स्ट्रिंग और उसके फॉर्मेटर के रिटर्न मान में 1 जोड़ देता है, कुछ ऐसा जो लूप के लिए पूरी तरह से अनदेखा करता है)।
विशेष रूप से, टिप्पणी की शुरुआत में उन एनयूएल वर्ण स्पष्ट रूप से किसी भी चीज़ से ऑफसेट नहीं हैं (यहां तक कि +8 और -4 के बीच का अंतर (
एनयूएल में बदलने के लिए पर्याप्त नहीं है )। वे 231-तत्व डेटा स्ट्रिंग को 241 तत्वों तक लाने के लिए शुद्ध पैडिंग हैं (जो आसानी से अपने लिए भुगतान करते हैं: यह पुनरावृत्तियों की संख्या की गणना करते समय 1 बनाम 239 के बजाय 1 बनाम 239 उत्पन्न करने के लिए दो से अधिक बाइट्स की आवश्यकता होगी। )। NUL का उपयोग पैडिंग कैरेक्टर के रूप में किया जाता था क्योंकि इसमें सबसे कम संभव कोडपॉइंट होता है (जिससे डेटा स्ट्रिंग के लिए सोर्स कोड कम होता है और इस प्रकार आउटपुट में तेजी आती है)।
{}({}())
शीर्ष स्टैक तत्व (हम जिस प्रारूप का उपयोग कर रहे हैं) को ड्रॉप करें, अगले में 1 जोड़ें (आउटपुट के लिए अंतिम वर्ण, यानी मुद्रित होने वाला पहला वर्ण, उस प्रोग्राम अनुभाग का जिसे हमने अभी स्वरूपित किया है)। हमें पुराने प्रारूप की कोई आवश्यकता नहीं है (नया प्रारूप कार्य स्टैक पर छिपा हुआ है); और वेतन वृद्धि ज्यादातर मामलों में हानिरहित है, और '
डेटा स्ट्रिंग फॉर्मैटर के स्रोत प्रतिनिधित्व के एक छोर पर एक (
(जो अगली बार जब हम फॉर्मेटर चलाते हैं, तो डेटा स्ट्रिंग को प्रारूपित करने के लिए आवश्यक है) में परिवर्तन होता है। हमें आउटरो या इंट्रो में इस तरह के परिवर्तन की आवश्यकता है, क्योंकि प्रत्येक डेटा स्ट्रिंग फॉर्मैटर तत्व को शुरू करने के लिए मजबूर (
करना इसे कुछ अधिक जटिल बना देगा (जैसा कि हमें (
बाद में बंद करना होगा और फिर इसके प्रभाव को पूर्ववत करना होगा), औरहमें किसी तरह एक अतिरिक्त (
कहीं उत्पन्न करने की आवश्यकता होगी क्योंकि हमारे पास केवल फॉर्मेट की लगभग 241 प्रतियां हैं, सभी 241 नहीं हैं (इसलिए यह सबसे अच्छा है कि एक हानिरहित चरित्र '
ऐसा है जो गायब है)।
(({})(()()()()){})
अंत में, लूप निकास परीक्षण। मुख्य स्टैक का वर्तमान शीर्ष वह प्रारूप है जिसकी हमें अगली पुनरावृत्ति के लिए आवश्यकता होती है (जो कि काम करने वाले स्टैक से वापस आ गया था)। यह इसे कॉपी करता है और कॉपी में 8 जोड़ता है; परिणामी मूल्य को अगली बार लूप के चक्कर में छोड़ दिया जाएगा। हालाँकि, अगर हम सिर्फ इंट्रो प्रिंट करते हैं, तो ऑफसेट -4 था तो "अगली पुनरावृत्ति" के लिए ऑफसेट -8 होगा; -8 + 8 0 है, इसलिए लूप पुनरावृति पर जारी रखने के बजाय बाहर निकल जाएगा।