संपादित करें: जैसा कि आप में से कुछ को संदेह था, आधिकारिक दुभाषिया में एक बग था: रचना का क्रम .
उलट गया था। मेरे पास दुभाषिया के दो संस्करण थे, और यहां गलत का इस्तेमाल किया। इस गलत संस्करण के लिए उदाहरण भी लिखे गए थे। मैंने रिपॉजिटरी में दुभाषिया, और नीचे दिए गए उदाहरणों को निर्धारित किया है। का वर्णन >
भी थोड़ा अस्पष्ट था, इसलिए मैंने यह तय किया है। इसके अलावा, इतनी देर लगने के लिए माफी, मुझे कुछ वास्तविक जीवन के सामान में पकड़ा गया था।
EDIT2: मेरे दुभाषिया के कार्यान्वयन में एक बग .
था , जो उदाहरणों में परिलक्षित हुआ (वे अपरिभाषित व्यवहार पर निर्भर थे)। मुद्दा अब तय हो गया है।
परिचय
Shift एक गूढ़ कार्यात्मक प्रोग्रामिंग भाषा है जिसे मैंने कुछ साल पहले बनाया था, लेकिन आज प्रकाशित किया गया है। यह स्टैक-आधारित है, लेकिन हास्केल की तरह स्वचालित करी भी है।
विशिष्टता
Shift में दो डेटाटिप्स हैं:
- फ़ंक्शंस, जिनमें एक मनमाना पॉजिटिव एरिटी (इनपुट्स की संख्या) है, और जो आउटपुट की एक सूची लौटाते हैं। उदाहरण के लिए, एक ऐसा फ़ंक्शन जो अपने एकमात्र इनपुट को डुप्लिकेट करता है, उसमें arity 1 है, और एक फ़ंक्शन जो इसके दो इनपुट स्वैप करता है, में arity 2 है।
- रिक्त स्थान, जो सभी समान हैं और कार्य नहीं होने के अलावा कोई अन्य उद्देश्य नहीं है।
Shift प्रोग्राम में शून्य या अधिक कमांड होते हैं , जिनमें से प्रत्येक एक ASCII वर्ण होता है। कुल 8 कमांड हैं:
!
( लागू ) एक कार्यf
औरx
स्टैक से एक मूल्य चबूतरे , औरf
करने के लिए लागू होता हैx
। यदिf
1 अंक है, तो सूचीf(x)
स्टैक के सामने जोड़ दी जाती है। यदि इसमें अरेटी हैn > 1
, तो एक नया-(n-1)
वैरिएबल फ़ंक्शनg
स्टैक पर धकेल दिया जाता है। यह इनपुट और रिटर्न लेता है ।x1,x2,...,xn-1
f(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
है !
, और उस के परिणाम को मुख्य स्टैक में जोड़ा जाता है।