संपादित करें: जैसा कि आप में से कुछ को संदेह था, आधिकारिक दुभाषिया में एक बग था: रचना का क्रम .उलट गया था। मेरे पास दुभाषिया के दो संस्करण थे, और यहां गलत का इस्तेमाल किया। इस गलत संस्करण के लिए उदाहरण भी लिखे गए थे। मैंने रिपॉजिटरी में दुभाषिया, और नीचे दिए गए उदाहरणों को निर्धारित किया है। का वर्णन >भी थोड़ा अस्पष्ट था, इसलिए मैंने यह तय किया है। इसके अलावा, इतनी देर लगने के लिए माफी, मुझे कुछ वास्तविक जीवन के सामान में पकड़ा गया था।
EDIT2: मेरे दुभाषिया के कार्यान्वयन में एक बग .था , जो उदाहरणों में परिलक्षित हुआ (वे अपरिभाषित व्यवहार पर निर्भर थे)। मुद्दा अब तय हो गया है।
परिचय
Shift एक गूढ़ कार्यात्मक प्रोग्रामिंग भाषा है जिसे मैंने कुछ साल पहले बनाया था, लेकिन आज प्रकाशित किया गया है। यह स्टैक-आधारित है, लेकिन हास्केल की तरह स्वचालित करी भी है।
विशिष्टता
Shift में दो डेटाटिप्स हैं:
- फ़ंक्शंस, जिनमें एक मनमाना पॉजिटिव एरिटी (इनपुट्स की संख्या) है, और जो आउटपुट की एक सूची लौटाते हैं। उदाहरण के लिए, एक ऐसा फ़ंक्शन जो अपने एकमात्र इनपुट को डुप्लिकेट करता है, उसमें arity 1 है, और एक फ़ंक्शन जो इसके दो इनपुट स्वैप करता है, में arity 2 है।
- रिक्त स्थान, जो सभी समान हैं और कार्य नहीं होने के अलावा कोई अन्य उद्देश्य नहीं है।
Shift प्रोग्राम में शून्य या अधिक कमांड होते हैं , जिनमें से प्रत्येक एक ASCII वर्ण होता है। कुल 8 कमांड हैं:
!( लागू ) एक कार्यfऔरxस्टैक से एक मूल्य चबूतरे , औरfकरने के लिए लागू होता हैx। यदिf1 अंक है, तो सूचीf(x)स्टैक के सामने जोड़ दी जाती है। यदि इसमें अरेटी हैn > 1, तो एक नया-(n-1)वैरिएबल फ़ंक्शनgस्टैक पर धकेल दिया जाता है। यह इनपुट और रिटर्न लेता है ।x1,x2,...,xn-1f(x,x1,x2,...,xn-1)?( ब्लैंक ) स्टैक को एक खाली धक्का देता है।+( क्लोन ) स्टैक के लिए एक यूनेरी फ़ंक्शन को धक्का देता है जो इसके इनपुट को डुप्लिकेट करता है: किसी भी मूल्यxको मैप किया जाता है[x,x]।>( शिफ्ट ) स्टैक को एकnअनियारी फंक्शन में धकेलता है जो एक- ऐरी फ़ंक्शन में लेता हैf, और एक-(n+1)थ्री-फंक्शनgदेता है जो इसके पहले तर्क को अनदेखा करता हैx,fशेष लोगों को कॉल करता है, औरxपरिणाम के सामने tacks । उदाहरण के लिए,shift(clone)एक बाइनरी फ़ंक्शन है जो इनपुटa,bऔर रिटर्न लेता है[a,b,b]।/( कांटा ) स्टैक को एक टर्नरी फ़ंक्शन को धक्का देता है जो तीन इनपुट लेता हैa,b,c, और रिटर्न[b]अगरaखाली है, और[c]अन्यथा।$( कॉल ) ढेर करने के लिए धक्का एक द्विआधारी समारोह एक समारोह पॉप किfऔर एक मूल्यxहै, और लागू होता हैfके लिएxबिल्कुल के रूप में!करता है।.( श्रृंखला ) ढेर करने के लिए एक द्विआधारी समारोह है कि पॉप दो कार्यों धक्काfऔरg, और उनकी संरचना देता है: एक समारोहhके रूप में ही arity हैf, और जो अपने आदानों आम तौर पर लेता है, पर लागू होता हैfउन्हें, और फिर पूरी तरह से लागू होता हैgपरिणाम के लिए (कॉल इसके परिणाम के रूप में अप्रयुक्त आइटम के साथ अप्रयुक्त वस्तुओं के साथ यह कई बारfहैh। उदाहरण के लिए, मान लीजिए किfएक द्विआधारी समारोह है कि अपने दूसरे तर्क क्लोन, और हैgहै कॉल । यदि स्टैक में शामिल है[f,g,a,b,c]और हम करते हैं.!!, तो इसमें शामिल है[chain(f,g),a,b,c]; अगर हम!!आगे करते हैं , तोfपहलेa,bउत्पादन के लिए लागू किया जाता है[a,b,b], तोgउस के पहले दो तत्वों पर लागू किया जाता है क्योंकि इसकी arity 2 है, उत्पादन[a(b),b], और स्टैक अंत में होगा[a(b),b,c]।@( कहते हैं ) एक अनियंत्रित फ़ंक्शन को धकेलता है जो केवल अपना इनपुट लौटाता है, और0यदि यह रिक्त था, और1यदि यह एक फ़ंक्शन था तो प्रिंट करता है।
ध्यान दें कि सभी कमांड !केवल स्टैक के लिए एक मूल्य को छोड़कर , इनपुट करने का कोई तरीका नहीं है, और किसी भी चीज़ को आउटपुट करने का एकमात्र तरीका उपयोग करना है @। एक कार्यक्रम एक-एक करके आदेशों का मूल्यांकन करके व्याख्या की है, मुद्रण 0या 1रों जब भी "कहते हैं कि" कहा जाता है, और बाहर निकलने। यहां वर्णित कोई भी व्यवहार नहीं है (रिक्त को लागू करना, लंबाई 0 या 1 के ढेर को लागू करना, रिक्त पर "चेन" कॉल करना) अपरिभाषित है: दुभाषिया दुर्घटनाग्रस्त हो सकता है, चुपचाप विफल हो सकता है, इनपुट के लिए पूछ सकता है, या जो भी हो।
काम
आपका कार्य Shift के लिए दुभाषिया लिखना है। इसे एसटीडीआईएन, कमांड लाइन, या फ़ंक्शन शिफ्ट प्रोग्राम की व्याख्या से लिया जाना चाहिए, और एसटीडीटी के लिए प्रिंट करें 0और 1एस और एस के परिणामी (संभवतः अनंत) आउटपुट को लौटाएं । यदि आप एक फ़ंक्शन लिखते हैं, तो आपको किसी तरह से अनंत-लंबाई वाले आउटपुट तक पहुंचने में सक्षम होना चाहिए (पायथन में जनरेटर, हास्केल में आलसी सूची, आदि)। वैकल्पिक रूप से, आप एक और इनपुट, एक संख्या ले सकते हैं n, और nआउटपुट के कम से कम अक्षरों को वापस कर सकते हैं यदि यह इससे अधिक लंबा है n।
सबसे कम बाइट गिनती जीतता है, और मानक खामियों को रोक दिया जाता है।
परीक्षण के मामलों
यह Shift प्रोग्राम प्रिंट करता है 01:
?@!@@!
बाईं ओर से शुरू करें: एक रिक्त धक्का दें, धक्का कहें , फिर रिक्त स्थान पर कहें । यह आउटपुट 0। फिर, दो बार कहें पुश करें , और दूसरे कहने को पहले पर लागू करें । यह आउटपुट 1।
यह कार्यक्रम हमेशा के लिए बंद हो जाता है, कोई उत्पादन नहीं:
$+.!!+!!
कॉल और क्लोन को पुश करें , फिर उन्हें चेन लागू करें (हमें दो !एस की आवश्यकता है क्योंकि चेन एक बाइनरी फ़ंक्शन है)। अब स्टैक में एक फ़ंक्शन होता है जो एक तर्क लेता है, इसे डुप्लिकेट करता है, और दूसरी पर पहली प्रति कहता है। इसके साथ +!!, हम इस फ़ंक्शन को डुप्लिकेट करते हैं और इसे स्वयं कहते हैं।
यह कार्यक्रम प्रिंट करता है 0010:
?@$.++>!.!!.!!.!!!!+?/!!!@!@>!!!
एक खाली धक्का और कहते हैं । फिर, एक द्विआधारी फ़ंक्शन की रचना करें जो इसके दूसरे तर्क की bप्रतिलिपि बनाता है, फिर पहले की प्रतिलिपि aबनाता है और खुद के साथ रचना करता है, फिर bलौटने पर रचना की प्रतिलिपि लागू करता है [a(a(b)),b]। इसे कहने के लिए लागू करें और रिक्त करें, फिर स्टैक पर शेष दो तत्वों पर कहें ।
यह कार्यक्रम प्रिंट करता है 0। प्रत्येक के लिए !!!जो आप इसे जोड़ते हैं, यह एक अतिरिक्त प्रिंट करता है 0।
?@+$>!>!+>!///!!>!>!.!!.!!.!!+!!!!
एक खाली धक्का और कहते हैं । फिर, एक टर्नरी फ़ंक्शन की रचना करें जो f,g,xइनपुट और रिटर्न के रूप में लेता है [f,f,g,g(x)]। उस फ़ंक्शन को क्लोन करें, और इसे खुद पर लागू करें, कहें और रिक्त करें। यह एप्लिकेशन स्टैक नहीं बदलता है, इसलिए हम फ़ंक्शन को जितनी बार चाहें उतनी बार फिर से लागू कर सकते हैं।
यह कार्यक्रम अनंत अनुक्रम को मुद्रित करता है 001011011101111..., जहां एस की संख्या 1हमेशा एक से बढ़ जाती है:
@?/!@>!??/!!>!+.!!.!!.!!.+>!.!!$$$$+$>!>!$>!>!+>!$>!>!>!+>!>!///!!>!>!>!.!!.!!.!!.!!.!!.!!.!!.!!.!!.!!+!!!!!
रिपॉजिटरी में एक एनोटेट संस्करण होता है।
f(x1, x2, ..., xn)और g(y1, y2, ..., ym)। कॉलिंग .दोनों को पॉप करता है और एक फ़ंक्शन को धक्का देता है h(z1, z2, ..., zn)। अब आप उन सभी तर्कों को धीरे-धीरे करके इसे खा सकते हैं !। इस nतरह के अनुप्रयोगों के बाद , शेष फ़ंक्शन में केवल एक तर्क था, और उस बिंदु पर यह गणना करता है f(z1, z2, ..., zn)(यानी आपके द्वारा fकिए गए सभी तर्कों पर लागू होता है), जो कुछ नए मूल्यों को धक्का देता है, और फिर तुरंत mस्टैक से मूल्यों का उपभोग करता है और gउन पर कॉल करता है।
.बिल्कुल मार्टिन के बताए अनुसार काम करता है, सिवाय इसके कि यदि मूल्यों fसे कम की सूची लौटाता है m, तो परिणाम अपरिभाषित है (रचना में समानता है n, इसलिए यह स्टैक से अधिक तर्क नहीं खा सकता है)। अनिवार्य रूप से, के आउटपुट का fउपयोग एक अस्थायी स्टैक के रूप में किया जाता है, जिस पर उपयोग करके gधक्का दिया जाता है और लागू किया जाता mहै !, और उस के परिणाम को मुख्य स्टैक में जोड़ा जाता है।