Prindeal (स्पष्ट prin-डी-अल ) एक नया है गूढ़ : प्रोग्रामिंग भाषा केवल चार आदेशों है कि जनसंपर्क पूर्णांक , में crement , डी crement , और अल आईएएस । इसकी अतिसूक्ष्मवाद के बावजूद, चार आज्ञाओं को चतुराई से जोड़कर, जटिल गणितीय क्रियाओं को Prindeal में किया जा सकता है।
इस कोड गोल्फ चैलेंज में आपका काम सबसे छोटा प्रोग्राम लिखना है जो Prindeal कोड चला सकता है।
युक्ति लंबी है, लेकिन मैंने इसे यथासंभव स्पष्ट करने की कोशिश की है और मेरा मानना है कि यदि आप Prindeal सीखने का प्रयास करते हैं तो आप इसे काफी सुंदर पाएंगे!
प्रीिन्डेल्ट की व्याख्या
preprocessing
एक Prindeal कार्यक्रम की व्याख्या करने से पहले इन चीजों को इस क्रम से इसे हटाने की आवश्यकता है:
#
रेखा के अंत में एक संकेत के बाद कुछ भी , इसके अलावा#
। (ये टिप्पणियां हैं।)- किसी भी लाइन पर व्हाट्सएप को पीछे छोड़ना।
- पूरी तरह से खाली लाइनें।
उदाहरण के लिए, Prindeal कार्यक्रम
p cat #The next line has 7 trailing spaces.
p dog
#p mouse
में रखा जाएगा
p cat
p dog
यहाँ से हम मान लेंगे कि यह प्रीप्रोसेसिंग कदम हो चुका है।
चर
हमें जल्दी से चर को दिखाने की जरूरत है कि वे कैसे उपयोग किए जाते हैं।
चर (और चर के संदर्भ) वे हैं जो Prindeal कमांड के तर्कों में पारित किए गए हैं। चर हमेशा वैश्विक होते हैं , इसलिए एक चर में संशोधन, चाहे वे कहीं भी हों, हर जगह परिलक्षित होते हैं।
प्रत्येक चर एक गैर-नकारात्मक मनमाना-सटीक पूर्णांक (0, 1, 2, 3, ...) रखता है । वेरिएबल्स को पूर्व-प्रारंभिक होने की आवश्यकता नहीं है - वे हमेशा मूल्य 0 से शुरू करते हैं पहली बार जब उनका उपयोग किया जाता है या कॉल किया जाता है।
- एक चर नाम अक्षर या अंक और अंडरस्कोर के किसी भी गैर रिक्त स्ट्रिंग है कि अंक के साथ शुरू नहीं करता है हो सकता है [a-zA-Z_][0-9a-zA-Z_]*
में regex । वे मामले संवेदनशील हैं, इसलिए spiny_lumpsuck3r
और Spiny_lumpsuck3r
विभिन्न चर हैं।
क्रियान्वयन
Prindeal एक अनिवार्य प्रोग्रामिंग भाषा है। जब एक Prindeal प्रोग्राम चलाया जाता है तो उसके कथन क्रम से ऊपर से नीचे की ओर निष्पादित होते हैं और फिर कार्यक्रम समाप्त होता है।
Prindeal प्रोग्राम में प्रत्येक गैर-इंडेंटेड लाइन एक स्टेटमेंट है जिसमें एकल कमांड का निष्पादन शामिल है जो तर्कों को ले सकता है या नहीं भी ले सकता है।
केवल उर्फ आदेशों के बाद संकेतित लाइनें होती हैं । विशेष रूप से, सिंगल स्पेस के साथ इंडेंट की गई तीन पंक्तियाँ हर उर्फ कमांड के बाद होती हैं और इसे इसका एक हिस्सा माना जाता है। तो अलियास बयान वास्तव में चार लाइनें लंबी हैं। (वे एक पंक्ति में हो सकते हैं, चार केवल अधिक पठनीय है।)
गैर उर्फ विवरण
उपनाम के अपवाद के साथ , एक Prindeal कार्यक्रम में प्रत्येक कथन का रूप है:
[command name] [argument 1] [argument 2] [argument 3] ...
मनमाने ढंग से तर्कों की संख्या हो सकती है (जिसमें कोई नहीं भी शामिल है)। प्रत्येक तर्क हमेशा एक चर या (जैसा कि हम देखेंगे जब उपनाम पर चर्चा करते हैं ) एक चर के संदर्भ में ।
एक बार निष्पादित होने के बाद, प्रत्येक कथन को असफलता या सफलता के रूप में चिह्नित किया जाता है जो इस बात पर निर्भर करता है कि त्रुटियां सामने आई थीं या नहीं। (यह केवल वास्तव में मायने रखता है जब हम उपनाम का उपयोग करने के लिए चारों ओर हो जाते हैं ।)
बिल्ट-इन प्रिंट , इंक्रीमेंट और डीक्रीमेंट उपरोक्त फॉर्म के साथ स्टेटमेंट हैं। यहाँ वे क्या करते हैं:
प्रिंट में कमांड नाम है
p
और एक तर्क लेता है। यह "=" द्वारा अलग किए गए चर के नाम और उसके मान (दशमलव में) को प्रिंट करता है, फिर एक नई रेखा। इसे हमेशा एक सफलता के रूप में चिह्नित किया जाता है ।उदाहरण के लिए, Prindeal कार्यक्रम
p _MyVariable_321 p screaming_hairy_armadillo
उत्पादन होगा
_MyVariable_321 = 0 screaming_hairy_armadillo = 0
क्योंकि सभी चर 0. पर शुरू होते हैं (बराबर चिह्न के पहले और बाद के रिक्त स्थान आवश्यक हैं।)
वेतन वृद्धि में कमांड नाम है
i
और एक तर्क लेता है। यह 1. द्वारा पारित चर के मूल्य में वृद्धि करता है। इसे हमेशा एक सफलता के रूप में चिह्नित किया जाता है ।उदाहरण के लिए, कार्यक्रम
i alpaca p alpaca i alpaca p alpaca
उत्पादन होगा
alpaca = 1 alpaca = 2
ध्यान दें कि कैसे
alpaca
0 से 1 तक बढ़ाई गई थी, हालांकि यह पहले कभी एक्सेस नहीं की गई थी।डिक्रीमेंट का कमांड नाम है
d
और एक तर्क लेता है। यदि पास किया गया वेरिएबल नॉनजेरो है तो उसका मान 1 से घट जाता है और स्टेटमेंट को सफलता के रूप में चिह्नित किया जाता है । यदि पारित किया गया चर 0 है तो कुछ भी नहीं किया जाता है और कथन को विफलता के रूप में चिह्नित किया जाता है ।उदाहरण के लिए, कार्यक्रम
i malamute p malamute d malamute #success p malamute d malamute #failure p malamute d akita #failure p akita
उत्पादन होगा
malamute = 1 malamute = 0 malamute = 0 akita = 0
ध्यान दें कि मान 0 के साथ एक चर घटाना एक विफलता का उत्पादन करने का एकमात्र तरीका है ।
उर्फ वक्तव्य और एलियास आदेश
उर्फ आदेश एक विशेष वाक्यविन्यास है और क्योंकि यह नए आदेश को परिभाषित करने के लिए किया जा सकता सबसे शक्तिशाली है। उर्फ आदेश नाम है a
और एक उर्फ बयान रूप है:
a [name of new command]
[statement A]
[statement B]
[statement C]
जहां प्रत्येक फॉर्म के साथ [statement X]
किसी गैर- उर्फ कथन का प्रतिनिधित्व करता है , यानी कुछ [command name] [argument 1] [argument 2] [argument 3] ...
।
अलियासिड कमांड का नाम [name of new command]
अल्फ़ान्यूमेरिक्स और अंडरस्कोर के किसी भी गैर-रिक्त स्ट्रिंग में हो सकता है जो कि अंक के साथ शुरू नहीं होता है - [a-zA-Z_][0-9a-zA-Z_]*
रेगेक्स में।
(यह चर के रूप में नामों का एक ही सेट है, लेकिन उपनाम वाले आदेश और चर अलग-अलग स्थानों में उपयोग की जाने वाली अलग-अलग चीजें हैं । एक चर को बिना किसी खराब परिणाम के कमांड के रूप में नाम दिया जा सकता है।)
जब किसी अन्य कथन को निष्पादित किया जाता है, तो मूल चार p
i
d
a
आदेशों के साथ एक नया आदेश जोड़ा जाता है । नए कमांड को [command name]
बयानों के रूप में इस्तेमाल किया जा सकता है और किसी अन्य गैर- उर्फ कमांड की तरह ही तर्कों के साथ बुलाया जा सकता है ।
जब किसी उपनाम वाले कमांड नाम के साथ एक कथन निष्पादित किया जाता है, तो उसके मूल उपनाम से दो और कथन चलाए जाते हैं:
[statement A]
हमेशा चलाया जाता है[statement B]
चलाया जाता है अगर[statement A]
एक सफलता थी[statement C]
यदि चलाया जाता है[statement A]
एक था विफलता
कथन A, B, और C को हमेशा आलस्यपूर्वक चलाया जाता है , अर्थात जब वे चलते हैं उस समय मक्खी पर उनका मूल्यांकन किया जाता है।
जब निष्पादित किया जाता है, तो अलियास कमांड को उसी सफलता या विफलता के झंडे के साथ बयान बी या सी के रूप में चिह्नित किया जाता है, जिसे भी निष्पादित किया गया था । ( उर्फ बयानों को स्वयं झंडी देने की आवश्यकता नहीं है क्योंकि वे अपने भीतर नहीं हो सकते।)
उपनाम 1 उदाहरण
मान लें कि हम एक नया आदेश चाहते हैं जो चर को
frog
दो बार बढ़ाता है । यह उपनाम विवरण इसे प्राप्त करता है:a increment_frog_twice i frog i frog d frog
कथन A (
i frog
) को हमेशा चलाया जाता है और हमेशा एक सफलता के रूप में चिह्नित किया जाता है इसलिए कथन B (i frog
) को भी हमेशा चलाया जाता है और चरfrog
को इस प्रकार बढ़ाया जाता है। 2.increment_frog_twice
कमांड को हमेशा एक सफलता के रूप में चिह्नित किया जाता है क्योंकि कथन B हमेशा चलाया जाता है और B हमेशा एक है सफलता । कथन C (d frog
) कभी नहीं चलाया जाता है।तो उत्पादन करने के लिए
a increment_frog_twice i frog i frog d frog p frog increment_frog_twice p frog
होने वाला
frog = 0 frog = 2
हम इस उदाहरण को सामान्य कर सकते हैं ताकि किसी भी चर को दो बार अलियास कमांड को तर्क देकर बढ़ाया जा सके।
एक उपनाम विवरण के भीतर सकारात्मक पूर्णांक 1, 2, 3, आदि 1, 2, 3, आदि का प्रतिनिधित्व करते हैं। तर्क अलियास कमांड में पारित हो जाते हैं। (ये तर्क सादे चर या स्वयं चर के संदर्भ हो सकते हैं।) ये संख्या केवल कथन A, B, और C के अन्य विवरणों में दिए गए तर्कों के भीतर दिखाई दे सकती हैं । यह उनके लिए कहीं और प्रकट होने का कोई मतलब नहीं है।
उपनाम उदाहरण २
यह अंतिम उदाहरण को सामान्य करता है - किसी भी चर को पारित किया
increment_twice
जाएगा जो कि 2 से बढ़ेगा क्योंकि1
पहले तर्क के लिए एक संदर्भ दिया गया है:a increment_twice i 1 i 1 d 1 #never reached p toad increment_twice toad p toad
इस कार्यक्रम का आउटपुट होगा
toad = 0 toad = 2
हम फिर एक अन्य आदेश को दो अन्य तर्कों और
increment_twice
उन दोनों पर कॉल करने में सक्षम कर सकते हैं:a increment_twice i 1 i 1 d 1 #never reached a increment_both_twice increment_twice 1 increment_twice 2 d 1 #never reached increment_both_twice platypus duck p platypus p duck
यहाँ उत्पादन होगा
platypus = 2 duck = 2
यह महसूस करना महत्वपूर्ण है कि अलियास कमांड पुनरावर्ती हो सकते हैं, क्योंकि यह वह जगह है जहां उनकी असली शक्ति निहित है। उदाहरण के लिए, हम एक कमांड बना सकते हैं जो किसी भी वैरिएबल को 0 में सेट करता है:
उपनाम उदाहरण 3
set_to_zero
आदेश एक तर्क लेता है और 0 के लिए अपने चर सेट करता है और एक के रूप में चिह्नित किया गया है सफलता जब किया:a set_to_zero d 1 set_to_zero 1 i _dummy_ i oryx i oryx i oryx p oryx set_to_zero oryx p oryx
इस कार्यक्रम का आउटपुट होगा
oryx = 3 oryx = 0
क्या हो रहा है कि जब
set_to_zero oryx
चलाया जाता है , तो 3 से 2 तकd 1
सफलतापूर्वक घटताoryx
है, फिरset_to_zero 1
कहा जाता है, जोset_to_zero oryx
फिर से कॉल करने के समान है । तो प्रक्रिया दोहराई जाती है जब तकd 1
कि विफलता नहीं होती है , पुनरावृत्ति को रोकना और_dummy_
चर को बढ़ाना ताकि एक सफलता का उत्पादन हो।
चुनौती
एक प्रोग्राम लिखें जो ऊपर वर्णित के अनुसार Prindeal कोड निष्पादित कर सकता है। स्टड, कमांड लाइन, या टेक्स्ट फ़ाइल के माध्यम से Prindeal कोड लें। प्रिंटआउट प्रोग्राम का आउटपुट प्रिंटआउट या आपकी भाषा के निकटतम विकल्प के लिए प्रिंट करें।
वैकल्पिक रूप से, आप एक फ़ंक्शन लिख सकते हैं जो कोड में स्ट्रिंग और प्रिंट के रूप में लेता है या आउटपुट स्ट्रिंग देता है।
इसके अतिरिक्त, आप मान सकते हैं कि:
- इनपुट Prindeal कोड में केवल newlines और प्रिंट करने योग्य ASCII और (वैकल्पिक रूप से) होगा जो इसे एक खाली लाइन के साथ समाप्त करता है।
- इनपुट कोड मान्य Prindeal होगा - अच्छी तरह से बना और वाक्यविन्यास सही होगा।
- कोड चलाने से कोई अनंत लूप नहीं बनेंगे और न ही कमांड के लिए कोई अमान्य संदर्भ जो परिभाषित नहीं किए गए हैं या तर्क जो नहीं दिए गए हैं।
- आदेश के नाम
p
,i
,d
, औरa
अधिक एलियास जा कभी नहीं होगा। (आप यह नहीं मान सकते हैं कि चर में ये नाम नहीं होंगे।)
इसके अलावा, इससे कोई फर्क नहीं पड़ता कि आपके चर मान वास्तव में मनमाने ढंग से सटीक पूर्णांक नहीं हैं क्योंकि लगभग 1000 से कम संख्या का परीक्षण किया जाएगा। यह भी ठीक है यदि आप भाषा में पुनरावृत्ति सीमाएँ (जैसे पायथन ) हैं कि अधिक जटिल Prindeal प्रोग्राम कार्य के नीचे परीक्षण कार्यक्रम के रूप में लंबे समय तक मुठभेड़ कर सकते हैं।
परीक्षण कार्यक्रम
यहाँ एक बड़ा Prindeal कार्यक्रम है जो डमी वैरिएबल्स ( _
कन्वेंशन के साथ शुरू ) और कई हेल्पर एलियासेस के उपयोग के अलावा जोड़, गुणा, और घातांक के संचालन को बनाता है :
#Command Definitions:
a s #flag as a success
i _
d _
d _
a f #flag as a failure
d _
d _
d _
a z #1 = zero
d 1
z 1
s
a n #1 = one
z 1
i 1
s
a move #2 += 1, 1 = zero
moveH 1 2
move 1 2
s
a moveH #move helper
d 1
i 2
f
a dupe #2 += 1, 3 += 1, 1 = zero
dupeH1 1 2 3
dupe 1 2 3
s
a dupeH1 #dupe helper
d 1
dupeH2 2 3
f
a dupeH2 #dupe helper
i 1
i 2
s
a copy #2 = 1
z 2
copyH 1 2
s
a copyH #copy helper
dupe 1 2 _copy
move _copy 1
s
a addTo #1 += 2
copy 2 _add
#testing comments #
move _add 1#in weird places # just because #
s
#it's a g##d idea
###
a add #1 = 2 + 3
#its a good idea
z 1
addH 1 2 3
s
##
#
a addH #add helper
#this is a comment
addTo 1 2 #as is this
addTo 1 3
s
a mul #1 = 2 * 3
mulH1 1 2
mulH2 1 3
s
a mulH1 #mul helper
z 1
copy 2 _mul
s
a mulH2 #mul helper
mulH3 1 2
mulH2 1 2
s
a mulH3 #mul helper
d _mul
addTo 1 2
f
a mulBy #1 *= 2
mul _mulBy 1 2
copy _mulBy 1
s
a pow #1 = 2^3
powH1 1 3
powH2 1 2
s
a powH1 #pow helper
n 1
copy 2 _pow
s
a powH2 #pow helper
powH3 1 2
powH2 1 2
s
a powH3 #pow helper
d _pow
mulBy 1 2
f
#Running Tests:
p A
p B
p C
n A #A = 1
n B #B = 1
add C A B #C = A + B = 1 + 1 = 2
p ____
p A
p B
p C
add B A C #B = A + C = 1 + 2 = 3
p ____
p A
p B
p C
mul d B C #d = B * C = 3 * 2 = 6
p ____
p d
mulBy d B #d = d * B = 6 * 3 = 18
p ____
p d
d A #A = A - 1 = 1 - 1 = 0
mulBy d A #d = d * A = 18 * 0 = 0
p ____
p d
pow A C B #A = C ^ B = 2 ^ 3 = 8
p ____
p A
p B
p C
pow A B C #A = B ^ C = 3 ^ 2 = 9
p ____
p A
p B
p C
pow C A B #C = A ^ B = 9 ^ 3 = 729
p ____
p A
p B
p C
(यदि आप इस कोड के साथ खेल रहे हैं तो ध्यान रखें कि यदि एक ही चर को एक तर्क के रूप में कई बार दिया गया है, तो कई कमांड विफल हो जाएंगे। यह आसानी से तय किया जा सकता है लेकिन परिणामी कोड लंबा है।)
आपका Prindeal दुभाषिया सटीक उत्पादन करने में सक्षम होना चाहिए:
A = 0
B = 0
C = 0
____ = 0
A = 1
B = 1
C = 2
____ = 0
A = 1
B = 3
C = 2
____ = 0
d = 6
____ = 0
d = 18
____ = 0
d = 0
____ = 0
A = 8
B = 3
C = 2
____ = 0
A = 9
B = 3
C = 2
____ = 0
A = 9
B = 3
C = 729
स्कोरिंग
बाइट्स में सबसे छोटा कोड जीतता है। टाईब्रेकर पहले जमा करने के लिए जाता है।
ब्राउनी बोनस: प्रिंडिल में एक शांत कार्यक्रम लिखें। मैंने जोड़ और गुणा लागू किया, क्या आप घटाव या विभाजन कर सकते हैं?
p
, और फिरp p
, जो 1 प्रिंट करेगा, ठीक है?