परिचय
कई प्रोग्रामर
क्वीन लिखने पर विचार करते हैं (ऐसे प्रोग्राम जो अपने सोर्स कोड को आउटपुट करते हैं) एक भारी काम है। और वास्तव में - ये सभी श्रृंखलाएं और विभिन्न आदेशों की विचित्रता, जब आप उन्हें देखते हैं तो आप वर्णों के एक बेकार अर्थ सेट में खो सकते हैं ...
हालांकि, वास्तव में, किसी भी भाषा में रानी लिखना उतना मुश्किल नहीं है जितना लगता है। अब मैं आपको बताऊंगा कि विभिन्न प्रोग्रामिंग भाषाओं में यह कैसे करना है। इसके अलावा, हम व्याख्या की गई भाषाओं के "हैक्स" का उपयोग नहीं करेंगे, जैसे कि सोर्सिंग कोड के आउटपुट के रूप में और eval जैसे फ़ंक्शन, और व्याख्या की गई और संकलित भाषाओं में क्वान लिखते हैं।
सिद्धांत
आइए रानी लिखने की कोशिश करते हैं। ऐसा करने के लिए, आउटपुट के लिए भाषा निर्देश लें और प्रोग्राम कोड को एक पैरामीटर के रूप में पास करें। हालांकि, कोड में हम फिर से उसी कोड का उपयोग करते हैं, और इसी तरह - अनंत पुनरावृत्ति होती है। लेकिन एक स्ट्रिंग स्थिरांक में पारित नहीं करने के लिए क्या किया जा सकता है? समाधान एक स्ट्रिंग (कोड के हिस्से की एक प्रति) को एक चर में डालना है। सुविधा के लिए, हम इस तरह के एक स्ट्रिंग को
एस-स्ट्रिंग कहेंगे, और इस स्ट्रिंग के साथ एक चर को
एस-चर कहा जाएगा। एस-चर में पुनरावृत्ति को रोकने के लिए, हम केवल इसे इस चर के मूल्य के साथ एक टुकड़े से बाहर रखते हैं। यही है, यह कुछ इस तरह दिखेगा:
सी:char s[]="char s[]=;";
नोट। इस टुकड़े में, साथ ही साथ क्वेंस में, जो परिणाम होगा, सादगी के लिए हम कोड फॉर्मेटिंग के नियमों का पालन नहीं करेंगे। फिर भी, आप लेख को पढ़ने के बाद आसानी से उन्हें लागू कर सकते हैं।इसके अलावा, आउटपुट पर, हम कोड में इसकी परिभाषा में एस-स्ट्रिंग के मूल्य को प्रतिस्थापित करते हैं (ऊपर के उदाहरणों में, अंतिम अक्षरों से पहले)। यहां कुछ और समस्याएं पैदा होती हैं। पहली समस्या यह है कि एस-लाइन में प्रतिस्थापन करते समय, आप उन वर्णों का उपयोग नहीं कर सकते हैं जो कोड में भिन्न व्यवहार करते हैं। उदाहरण के लिए, हम एक उद्धरण चिह्न इतनी आसानी से नहीं डाल सकते हैं - क्योंकि एस-स्ट्रिंग का हिस्सा बनने के बजाय, यह अपनी परिभाषा को पूरा करेगा और प्रदर्शित कोड मूल से मेल नहीं खाएगा, बिल्कुल गलत हो रहा है।
बचने के लिए यहां आवेदन करना मुश्किल है - भागने वाले चरित्र को भी बच जाना चाहिए, आदि यह बहुत सरल है, उदाहरण के लिए, उद्धरण चिह्नों के एक अलग संस्करण का उपयोग करने के लिए - उदाहरण के लिए, कई व्याख्या की गई भाषाओं में एक स्ट्रिंग को निर्दिष्ट करने के लिए एकल या दोहरे उद्धरण चिह्नों के उपयोग की अनुमति है, और अंतर है। यदि यह समस्याओं के बिना एक निरंतर में एक उद्धरण का उपयोग करना संभव है, अगर यह दूसरों तक सीमित है। यही है, कोड
'"'
एक एकल-वर्ण स्ट्रिंग को दोहरे उद्धरण के साथ और कोड
"'"
को एकल उद्धरण के साथ बनाएगा। यदि आप इस विकल्प का उपयोग करते हैं, तो शुरुआत में एक उद्धरण के साथ एक चर सेट करना सुविधाजनक है, और फिर आउटपुट में इसका उपयोग करें।
लेकिन यह विकल्प सार्वभौमिक नहीं है: सी में, उदाहरण के लिए, उद्धरण चिह्नों के लिए केवल एक ही विकल्प है। फिर आप एक अन्य विधि का उपयोग कर सकते हैं - वर्ण कोड के साथ उद्धरण चिह्न निर्दिष्ट करें, आउटपुट पर इस तरह के कोड के साथ एक चरित्र को प्रिंट करना।
अगली समस्या एस-लाइन के आउटपुट में एक और लाइन (या कुछ कोड के साथ एक चरित्र) डाल रही है। यहाँ समाधान स्पष्ट है - एक विशेष फ़ंक्शन के साथ एस-स्ट्रिंग के विकल्प को लें, इसे आउटपुट करें, फिर आउटपुट जिसे आपको सम्मिलित करने की आवश्यकता है, फिर एस-स्ट्रिंग के एक और विकल्प को आउटपुट करें। ऐसा लगता है कि सी में, आउटपुट के लिए एक विकल्प लेने के लिए बहुत सारे कोड की आवश्यकता होगी। यहां प्रिंटफ फ़ंक्शन की शक्ति हमारी सहायता के लिए आती है। इसलिए, उदाहरण के लिए, यहां विभिन्न भाषाओं के लिए कोड विकल्प हैं, दूसरे वर्ण से स्ट्रिंग एस का हिस्सा प्रिंट करना (एक से गिनती) चौथे से, समावेशी:
अजगर: print(s[1:4])
रूबी: print s[1..3]
पर्ल: print substr(s,1,2)
सी: printf("%.2s",s+1)
आमतौर पर, प्रतिस्थापन विधियाँ भी इसके शेष को अंत तक ले जा सकती हैं। उदाहरण के लिए, दूसरे वर्ण से पंक्ति के अंत तक स्ट्रिंग s को प्रिंट करें (अर्थात, प्रथम वर्ण को छोड़कर पूरी पंक्ति):
अजगर: print(s[1:])
रूबी: print s[1..-1]
पर्ल: print substr(s,1)
सी: printf("%s",s+1);
यदि यह संभव नहीं है, तो आपको पैरामीटर को प्रतिस्थापित करना होगा प्रकार की लंबाई के साथ "XX" स्टब के साथ पैरामीटर, और फिर अंत में वर्णों को गिनती में और कोड के विभिन्न भागों की लंबाई को बदले बिना, कोड में और एस-लाइन में "एक्सएक्स" के साथ उन्हें प्रतिस्थापित करना होगा। उदाहरण के लिए, यदि लंबाई में एक अंक है, तो पहले एक्स के बजाय एक स्थान को प्रतिस्थापित करना उचित है, क्योंकि यदि आप इसे हटाते हैं, तो एस-स्ट्रिंग भागों की लंबाई बदल जाएगी और उन्हें फिर से जोड़ना होगा।
व्याख्या की गई भाषाएँ
तो, चलिए उपरोक्त सभी निर्णयों को एकत्रित करते हुए, Quines लिखना शुरू करते हैं।
पायथन में, मैंने यह क्वीन लिखा था (यह
3.x पर काम करता है):
q="'";s='q="";s=;print(s[:3]+q+s[3:7]+q+s+q+s[7:])';print(s[:3]+q+s[3:7]+q+s+q+s[7:])
यहाँ, q वैरिएबल को एक वैरिएबल के रूप में प्रयोग किया जाता है, जहाँ एक सिंगल कोट्स को स्टोर किया जाता है, फिर s- वेरिएबल को s-string के अलावा सभी कोड के साथ परिभाषित किया जाता है। उसके बाद निम्नलिखित आवेषण के साथ एस-चर का आउटपुट आता है:
1)। Q के मूल्य के रूप में एकल उद्धरण;
2)। एस-स्ट्रिंग परिभाषा की शुरुआत के रूप में एक एकल उद्धरण;
3)। खुद एस-स्ट्रिंग (हाँ, एस-स्ट्रिंग को एस-स्ट्रिंग के अंदर डाला जाता है);
4)। एस-स्ट्रिंग परिभाषा के अंत के रूप में एक एकल उद्धरण।
नोट। जब इस विधि का उपयोग करके क्वीन लिखते हैं, तो कोड में सभी परिवर्तनों को एस-लाइन में कोड की एक प्रति में कॉपी करना न भूलें।न्यूनतम संशोधनों के साथ, आप केवल
पायथन 2.x के लिए क्वीन प्राप्त कर सकते हैं:
q="'";s='q="";s=;print s[:3]+q+s[3:7]+q+s+q+s[7:]';print s[:3]+q+s[3:7]+q+s+q+s[7:]
अन्य भाषाओं में Quines बिल्कुल समान हैं, जहां हम केवल कुछ वाक्यात्मक विशेषताएं बदलते हैं:
रूबी: q="'";s='q="";s=;print s[0..2]+q+s[3..6]+q+s+q+s[7..-1]';print s[0..2]+q+s[3..6]+q+s+q+s[7..-1]
पर्ल: $q="'";$s='$q="";$s=;print substr($s,0,4).$q.substr($s,4,5).$q.$s.$q.substr($s,9)';print substr($s,0,4).$q.substr($s,4,5).$q.$s.$q.substr($s,9)
पीएचपी: <?$q="'";$s='<?$q="";$s=;print substr($s,0,6).$q.substr($s,6,5).$q.$s.$q.substr($s,11);';print substr($s,0,6).$q.substr($s,6,5).$q.$s.$q.substr($s,11);
संकलित भाषाएँ।
C में क्वीन लिखना थोड़ा अधिक कठिन साबित हुआ है। यहां मैंने सक्रिय रूप से चरित्र कोड का उपयोग किया है: दोहरे उद्धरण चिह्नों - 34, और लाइन फीड - 13 (इसे stdio.h को शामिल करने के लिए संकलक निर्देश को अलग करने की आवश्यकता थी), साथ ही साथ पहले से ही वर्णित प्रिंटफ का उपयोग करके प्रतिस्थापन लेने का एक दिलचस्प तरीका है।
और यहाँ खुद ही है:
#include <stdio.h> int main(){const char *s="#include <stdio.h>int main(){const char *s=;printf(%.18s%c%.25s%c%s%c%.8s%c%.33s%c%s,s,10,s+18,34,s,34,s+43,34,s+51,34,s+84);return 0;}";printf("%.18s%c%.25s%c%s%c%.8s%c%.33s%c%s",s,10,s+18,34,s,34,s+43,34,s+51,34,s+84);return 0;}
निष्कर्ष
वह सब है। मैंने अधिकांश भाषाओं में क्वेस्चन लिखे, जिन व्याख्याताओं और संकलकों को मैंने अपने कंप्यूटर पर पाया। मुझे लगता है कि अब आप स्वयं भी अपनी पसंदीदा प्रोग्रामिंग भाषा में एक समान प्रोग्राम लिखेंगे, अगर मैंने इसका उल्लेख यहां नहीं किया है। व्यायाम के रूप में, आप जावा, सी #, हास्केल, या पास्कल जैसी भाषाओं में भी क्वीन लिख सकते हैं। कठिनाइयों से डरो मत - बस कोशिश करो और सब कुछ बाहर काम करेगा!