1. मूल बातें
Brainfuck को समझने के लिए आपको 0
प्रत्येक द्वारा आरम्भ की गई कोशिकाओं की अनंत सरणी की कल्पना करनी चाहिए ।
...[0][0][0][0][0]...
जब ब्रेनफक प्रोग्राम शुरू होता है, तो यह किसी भी सेल की ओर इशारा करता है।
...[0][0][*0*][0][0]...
यदि आप प्वाइंटर को दाएं घुमाते हैं तो आप >
सेल X से सेल X + 1 में पॉइंटर को ले जा रहे हैं
...[0][0][0][*0*][0]...
यदि आप सेल वैल्यू बढ़ाते हैं +
तो आपको मिलेगा:
...[0][0][0][*1*][0]...
यदि आप फिर से सेल वैल्यू बढ़ाते हैं +
तो आपको मिलेगा:
...[0][0][0][*2*][0]...
यदि आपको सेल वैल्यू में कमी आती है -
:
...[0][0][0][*1*][0]...
यदि आप पॉइंटर को छोड़ते हैं <
तो आप सेल X से सेल X-1 में पॉइंटर को ले जाते हैं
...[0][0][*0*][1][0]...
2. इनपुट
चरित्र पढ़ने के लिए आप कॉमा का उपयोग करते हैं ,
। यह क्या करता है: मानक इनपुट से चरित्र पढ़ें और वास्तविक सेल में इसके दशमलव ASCII कोड लिखें।
ASCII तालिका पर एक नज़र डालें । उदाहरण के लिए, दशमलव कोड !
है 33
, जबकि a
है 97
।
खैर, अपने बीएफ कार्यक्रम की स्मृति की कल्पना की तरह दिखता है:
...[0][0][*0*][0][0]...
मान लिया जाए कि मानक इनपुट का अर्थ है a
, यदि आप अल्पविराम ,
ऑपरेटर का उपयोग करते हैं , तो BF मेमोरी में a
ASCII कोड क्या पढ़ता है 97
:
...[0][0][*97*][0][0]...
आप आम तौर पर उस तरह से सोचना चाहते हैं, हालांकि सच्चाई थोड़ी अधिक जटिल है। सच्चाई यह है कि बीएफ एक चरित्र नहीं बल्कि एक बाइट (जो भी बाइट है) पढ़ता है। मैं आपको उदाहरण दिखाता हूं:
लिनक्स में
$ printf ł
प्रिंट:
ł
जो विशिष्ट पॉलिश चरित्र है। यह चरित्र ASCII एन्कोडिंग द्वारा एन्कोड नहीं किया गया है। इस मामले में यह UTF-8 एन्कोडिंग है, इसलिए यह कंप्यूटर मेमोरी में एक से अधिक बाइट लेता था। हम इसे हेक्साडेसिमल डंप बनाकर साबित कर सकते हैं:
$ printf ł | hd
जो दीखता है:
00000000 c5 82 |..|
जीरो ऑफसेट हैं। 82
पहला है और c5
दूसरा बाइट का प्रतिनिधित्व करता है ł
(क्रम में हम उन्हें पढ़ेंगे)। |..|
चित्रमय प्रतिनिधित्व है जो इस मामले में संभव नहीं है।
यदि आप ł
अपने बीएफ प्रोग्राम के इनपुट के रूप में पास होते हैं, जो सिंगल बाइट को पढ़ता है, तो प्रोग्राम मेमोरी इस तरह दिखाई देगी:
...[0][0][*197*][0][0]...
क्यों 197
? अच्छी तरह से 197
दशमलव c5
हेक्साडेसिमल है। परिचित लगता है? बेशक। यह पहली बाइट है ł
!
3. आउटपुट
वर्ण प्रिंट करने के लिए आप डॉट का उपयोग करते हैं, .
जो यह है: मान लें कि हम वास्तविक सेल मान को दशमलव ASCII कोड की तरह मानते हैं, मानक चरित्र के अनुरूप चरित्र प्रिंट करें।
खैर, अपने बीएफ कार्यक्रम की स्मृति की कल्पना की तरह दिखता है:
...[0][0][*97*][0][0]...
यदि आप डॉट (?) ऑपरेटर का उपयोग करते हैं, तो BF क्या प्रिंट करता है:
ए
क्योंकि a
ASCII में दशमलव कोड है 97
।
तो उदाहरण के लिए बीएफ प्रोग्राम इस तरह (97 प्लस 2 डॉट्स):
++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++ ..
सेल के मूल्य में वृद्धि करेगा जो इसे 97 तक बताता है और इसे 2 बार प्रिंट करता है।
आ
4. लूप्स
BF लूप में लूप स्टार्ट [
और लूप एंड होते हैं ]
। आप सोच सकते हैं कि यह C / C ++ में है, जहां स्थिति वास्तविक सेल वैल्यू है।
नीचे देखिए BF प्रोग्राम
++[]
++
दो बार वास्तविक सेल मूल्य में वृद्धि:
...[0][0][*2*][0][0]...
और []
पसंद है while(2) {}
, इसलिए यह अनंत लूप है।
मान लें कि हम नहीं चाहते कि यह लूप अनंत हो। हम उदाहरण के लिए कर सकते हैं:
++[-]
तो हर बार एक लूप लूप में वास्तविक सेल वैल्यू घटाता है। एक बार वास्तविक सेल वैल्यू 0
लूप समाप्त हो जाती है:
...[0][0][*2*][0][0]... loop starts
...[0][0][*1*][0][0]... after first iteration
...[0][0][*0*][0][0]... after second iteration (loop ends)
आइए अभी तक परिमित पाश का एक और उदाहरण देखें:
++[>]
यह उदाहरण दिखाता है, हमने उस सेल में लूप खत्म नहीं किया है जो लूप पर शुरू हुआ था:
...[0][0][*2*][0][0]... loop starts
...[0][0][2][*0*][0]... after first iteration (loop ends)
हालाँकि जहाँ हमने शुरू किया था उसे समाप्त करना अच्छा है। क्यों ? क्योंकि यदि लूप किसी अन्य सेल को शुरू करता है, तो हम यह नहीं मान सकते कि सेल पॉइंटर कहां होगा। ईमानदार होने के लिए, यह अभ्यास दिमाग को कम दिमागदार बनाता है।