प्रिंट, वेतन वृद्धि, कमी, उपनाम - व्याख्या की व्याख्या


30

Prindeal (स्पष्ट prin-डी-अल ) एक नया है गूढ़ : प्रोग्रामिंग भाषा केवल चार आदेशों है कि जनसंपर्क पूर्णांक , में crement , डी crement , और अल आईएएस । इसकी अतिसूक्ष्मवाद के बावजूद, चार आज्ञाओं को चतुराई से जोड़कर, जटिल गणितीय क्रियाओं को Prindeal में किया जा सकता है।

इस कोड गोल्फ चैलेंज में आपका काम सबसे छोटा प्रोग्राम लिखना है जो Prindeal कोड चला सकता है।

युक्ति लंबी है, लेकिन मैंने इसे यथासंभव स्पष्ट करने की कोशिश की है और मेरा मानना ​​है कि यदि आप Prindeal सीखने का प्रयास करते हैं तो आप इसे काफी सुंदर पाएंगे!


प्रीिन्डेल्ट की व्याख्या

preprocessing

एक Prindeal कार्यक्रम की व्याख्या करने से पहले इन चीजों को इस क्रम से इसे हटाने की आवश्यकता है:

  1. #रेखा के अंत में एक संकेत के बाद कुछ भी , इसके अलावा #। (ये टिप्पणियां हैं।)
  2. किसी भी लाइन पर व्हाट्सएप को पीछे छोड़ना।
  3. पूरी तरह से खाली लाइनें।

उदाहरण के लिए, 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] ...

मनमाने ढंग से तर्कों की संख्या हो सकती है (जिसमें कोई नहीं भी शामिल है)। प्रत्येक तर्क हमेशा एक चर या (जैसा कि हम देखेंगे जब उपनाम पर चर्चा करते हैं ) एक चर के संदर्भ में

एक बार निष्पादित होने के बाद, प्रत्येक कथन को असफलता या सफलता के रूप में चिह्नित किया जाता है जो इस बात पर निर्भर करता है कि त्रुटियां सामने आई थीं या नहीं। (यह केवल वास्तव में मायने रखता है जब हम उपनाम का उपयोग करने के लिए चारों ओर हो जाते हैं ।)

बिल्ट-इन प्रिंट , इंक्रीमेंट और डीक्रीमेंट उपरोक्त फॉर्म के साथ स्टेटमेंट हैं। यहाँ वे क्या करते हैं:

  1. प्रिंट में कमांड नाम है pऔर एक तर्क लेता है। यह "=" द्वारा अलग किए गए चर के नाम और उसके मान (दशमलव में) को प्रिंट करता है, फिर एक नई रेखा। इसे हमेशा एक सफलता के रूप में चिह्नित किया जाता है ।

    उदाहरण के लिए, Prindeal कार्यक्रम

    p _MyVariable_321
    p screaming_hairy_armadillo
    

    उत्पादन होगा

    _MyVariable_321 = 0
    screaming_hairy_armadillo = 0
    

    क्योंकि सभी चर 0. पर शुरू होते हैं (बराबर चिह्न के पहले और बाद के रिक्त स्थान आवश्यक हैं।)

  2. वेतन वृद्धि में कमांड नाम है iऔर एक तर्क लेता है। यह 1. द्वारा पारित चर के मूल्य में वृद्धि करता है। इसे हमेशा एक सफलता के रूप में चिह्नित किया जाता है ।

    उदाहरण के लिए, कार्यक्रम

    i alpaca
    p alpaca
    i alpaca
    p alpaca
    

    उत्पादन होगा

    alpaca = 1
    alpaca = 2
    

    ध्यान दें कि कैसे alpaca0 से 1 तक बढ़ाई गई थी, हालांकि यह पहले कभी एक्सेस नहीं की गई थी।

  3. डिक्रीमेंट का कमांड नाम है 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 प्रिंट करेगा, ठीक है?
orlp

@orlp सही। (वहाँ के बारे में कुछ नोट्स हैं।)
केल्विन के शौक

2
जब मैं भाषा का नाम देखता हूं तो मैं केवल वही नहीं होता जो PRNDL सोचता है।
डाउनगोट

क्या अधिकतम तर्क हैं जो किसी अन्य कमांड को पारित किए जाएंगे?
Zach गेट्स

जवाबों:


9

पायथ, 162 136 बाइट्स

JfTmchcd\#).zKHW<ZlJI!e=T@J~+Z1=@Tk)=k0 .x=J+]h=Nm.xL@Tskd@K=NhT+]+tN0>J~Z0,=Y.x@H=eT0?qN\pps[Td\=dYb)?xGN?qN\iXHThY?YXTH_1=k1XKT:JZ=+Z3

प्रदर्शन।

चर को इनलाइन और से बदलकर 26 वर्ण golfed Iऔर Eआधारित नियंत्रण प्रवाह करने के लिए ?और .xआधारित नियंत्रण प्रवाह।

पहली बार, मैं पायथ में चर से बाहर भागा। पायथ ( bdkGHNTYऔर JK) में हर एक चर उपयोग में था, और मैं bएक नई पंक्ति के रूप में उपयोग करना चाहता था । सौभाग्य से, मैं Nकार्यक्रम के विभिन्न हिस्सों में दो पूरी तरह से अलग-अलग चीजों का उपयोग करने में सक्षम था , और इसलिए यह अभी भी काम करता है।

अनगुल्ड (एमएम के साथ भागो):

JfTmchcd\#).z
KH
W<ZlJ
  I!e=T@J~+Z1
    =@Tk)
  =k0
     .x
      =J+]h=Nm.xL@Tskd@K=NhT+]+tN0>J~Z0
      ,
        =Y.x@H=eT0
        ?qN\p
          ps[Td\=dYb)
          ?xGN
            ?qN\i
              XHThY
              ?Y
                XTH_1
                =k1
            XKT:JZ=+Z3

3
मैं प्यार करता हूँ कि कैसे मैं अभी भी यह नहीं बता सकता कि यह इसके साथ क्या करता है ...
जेरी यिर्मयाह

ठीक है, यह निष्कर्ष है कि पायथ नॉन-ट्यूरिंग-कम्प्लीट है ...
एरिक आउट द ऑल्फर

8

पायथन 2, 600 584 397 373 बाइट्स

यह मेरा अपना गोल्फ संदर्भ समाधान है। किसी को भी इसे सुधारने या अपने स्वयं के उत्तर में अपने तर्क का पालन करने के लिए स्वागत है जब तक कि अटेंशन दिया जाता है।

इसके बारे में साफ-सुथरा हिस्सा यह है कि कोई भी पुनरावृत्ति नहीं की जाती है, इसलिए इसे पायथन की पुनरावृत्ति सीमा के साथ समस्या नहीं होगी। उदाहरण के लिए, Sp's Countup Prindeal प्रोग्राम अनिश्चित काल तक चल सकता है।

p=filter(len,[l.split('#')[0].split()for l in input().split('\n')]);m={};v={};i=0
while i<len(p):
 s=p[i]
 if'('in`s`:s=s[f]
 n,f=s[0],0
 if n in m:a,b,c=([s[int(g)]if g.isdigit()else g for g in t]for t in m[n]);p=[a,(b,c)]+p[i+1:];i=0;continue
 s=s[1]
 q=v.get(s,0)
 if'd'>n:m[s]=p[i+1:i+4];i+=3
 elif'i'<n:print s,'=',q
 elif'd'<n:v[s]=q+1
 elif q:v[s]-=1
 else:f=1
 i+=1

यह एक ऐसा प्रोग्राम है जो उद्धृत प्रोग्राम स्ट्रिंग में लेता है, जिसमें नई सुचना बच जाती है, जैसे
'p _MyVariable_321\np screaming_hairy_armadillo'

मैंने Sp और Pietu के उत्तरों से विभिन्न गोल्फिंग संकेत लिए । धन्यवाद दोस्तों :)


6

पायथन 3, 345 336 335 328 बाइट्स

a=0
A={}
V={}
def f(l):
 if l[0]in"d p i":c,u=l;U=V[u]=V.get(u,0)+"pi".find(c);S=U<0;V[u]+=S;c<"p"or print(u,"=",U)
 else:d=lambda q:[w.isdigit()and l[int(w)]or w for w in A[l[0]][q]];S=f(d(1+f(d(0))))
 return S
for z in open("P"):
 l=z.split("#")[0].split()
 if"a "==z[:2]:a,s,*x=3,l[1]
 elif l*a:x+=l,;a-=1;A[s]=x
 elif l:f(l)

(-6 बाइट्स @ थोरप को धन्यवाद)

फिर भी गोल्फ। मान लें कि प्रोग्राम नाम की फ़ाइल में संग्रहीत है P

लैंबडा के fअंदर कॉल डालने से dकुछ बाइट्स बचते हैं, लेकिन यह आखिरी टेस्ट केस को अधिकतम रिकर्सन डेप्थ हिट कर देगा।

कुछ Prindeal कार्यक्रम

बेकार घटाव कार्यक्रम

यहाँ एक बेकार घटाव कार्यक्रम है । यह बेकार है, क्योंकि भले ही यह ठीक से घटता है, यह तदनुसार सफलता / विफलता नहीं लौटाता है।

आउटपुट होना चाहिए:

a = 15
b = 6
__________ = 0
a = 9
b = 6

गिनती

a helper
 p 1
 countup 1
 i success

a countup
 i 1
 helper 1
 d failure

countup n

ऊपर की ओर गिना जाता है और nहमेशा के लिए प्रिंट करता है। संभवतः दुभाषिया गति के लिए एक परीक्षण के रूप में काम कर सकता है (कीबोर्ड इंटरप्ट पर लंबी ट्रेसबैक से सावधान रहें)।


2
इस सवाल पर हर कोई इस गोल्फ से चूक गया है, मुझे समझ नहीं आता कि क्यों। l[:(l+"#").find("#")]और इसके सभी रूपांतरों को एक साधारण से बदला जा सकता है l.split('#')[0]
orlp

@orlp पर इतना ध्यान केंद्रित किया गया था findकि मैं भूल गया था splitकि अगर आप #वहां नहीं थे तो भी आप भूल सकते हैं धन्यवाद :)
Sp3000

6

जावास्क्रिप्ट (ईएस 6), 273 258

फिक्स्ड बग संपादित करें और एक वास्तविक परीक्षण सूट जोड़ा।

प्रमुख स्थानों और newlines गिनती नहीं।

निश्चित रूप से थोड़ा और गोल्फ हो सकता है।

अब एक स्पष्टीकरण लिखने के लिए बहुत थक गया, मुझे लगता है कि यह जीवित अस्थायी मूल्यों (मापदंडों) को बनाए रखने के लिए क्लोजर का उपयोग करने का एक अच्छा उदाहरण है।

किसी भी EcmaScript 6 अनुरूप ब्राउज़र पर स्निपेट का परीक्षण करना (विशेष रूप से क्रोम नहीं MSIE। मैंने फ़ायरफ़ॉक्स, सफारी 9 पर परीक्षण किया जा सकता है)।

F=p=>(
  p=p.match(/^[^#\n]+/gm).filter(r=>r.trim(o='',v=[])),
  s={
    '':_=>1,
    p:a=>o+=a+` = ${v[a]||0}\n`,
    i:a=>v[a]=-~v[a],
    d:a=>v[a]&&v[a]--,
    a:(n,j)=>s[n]=(u,t,a)=>x(p[!x(p[j+1],0,a,1)+j+2],0,a,1)
  },
  p.map(x=(r,i,w,l,a=r.split(/ +/).slice(l).map(x=>-x?w[x]:x))=>s[a[0]](a[1],i,a)),
  o
)

// TEST

$('#O tr').each(function() {
  var $cells = $(this).find('td')
  var prg = $cells.eq(0).text()
  console.log(prg)
  var output = F(prg)
  $cells.eq(1).text(output)
})
#O td { vertical-align:top; white-space: pre; border: 1px solid #888; font-family:monospace }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table>
<tr><th>Program</th><th>Outpout</th></tr>
<tbody id=O>  
<tr><td>p _MyVariable_321
p screaming_hairy_armadillo</td><td></td></tr>
<tr><td>i alpaca
p alpaca
i alpaca
p alpaca</td><td></td></tr>
<tr><td>i malamute
p malamute
d malamute    #success
p malamute
d malamute    #failure
p malamute
d akita       #failure
p akita</td><td></td></tr>
<tr><td>a increment_frog_twice
 i frog
 i frog
 d frog
p frog
increment_frog_twice
p frog</td><td></td></tr>
<tr><td>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</td><td></td></tr>
<tr><td>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</td><td></td></tr>
<tr><td>#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  
</td><td></td></tr>
</tbody>
</table>


मैंने परीक्षण कार्यक्रम में कुछ और टिप्पणियाँ जोड़ी हैं और ऐसा लगता है कि उन्होंने आपका कोड काम नहीं किया।
केल्विन के शौक

@ केल्विन के शौकीनों का पहला, त्वरित पैच
edc65

3

सी # 6, 653 बाइट्स

यहाँ मेरी एंट्री है, अजगर के एक समुद्र के बीच ...

class P{string[]l;string r="";Dictionary<string,int>v=new Dictionary<string,int>();Dictionary<string,int>s=new Dictionary<string,int>();public string R(string t){l=t.Split('\n');for(int i=0;i<l.Length;i++){var z=l[i].Split(' ');if(z[0]=="a"){s.Add(z[1],i);i+=3;}else E(i, null);}return r;}bool E(int n,string[]p){var z=l[n].Split(' ');var a=z.Skip(1).Select(x=>Char.IsDigit(x[0])?p[int.Parse(x)-1]:x).ToArray();if(a.Length>0&&!v.ContainsKey(a[0]))v[a[0]]=0;if (z[0]=="p")r+=$"{a[0]} = {v[a[0]]}\n";else if(z[0]=="i")v[a[0]]++;else if(z[0]=="d")if(v[a[0]]>0)v[a[0]]--;else return false;else{var y=s[z[0]];return E(y+1,a)?E(y+2,a):E(y+3,a);}return true;}}

विस्तृत और टिप्पणी:

class Prindeal
{
    string[] lines;
    string result = "";
    Dictionary<string, int> variables = new Dictionary<string, int>();
    Dictionary<string, int> statements = new Dictionary<string, int>();

    public string Run(string text)
    {
        lines = text.Split('\n');

        for (int i = 0; i < lines.Length; i++)
        {
            // Split on spaces to get the statement and any arguments
            var z = lines[i].Split(' ');

            // Are we defining a new statement?
            if (z[0] == "a")
            {
                // Add to the statements dictionary, step over definition statements
                statements.Add(z[1], i);
                i += 3;
            }
            else
            {
                // Execute the statement
                Execute(i, null);
            }
        }

        return result;
    }

    bool Execute(int lineNumber, string[] parameters)
    {
        // Split on spaces to get the statement and any arguments
        var z = lines[lineNumber].Split(' ');

        // Parse the arguments - if it's a number, get the corresponding 
        // parameter from the calling statement
        var arguments = z.Skip(1).Select(
            x => Char.IsDigit(x[0]) ? 
            parameters[int.Parse(x) - 1] : 
            x)
            .ToArray();

        // If the first argument isn't already in the variables dict, add it
        if (arguments.Length > 0 && !variables.ContainsKey(arguments[0])) variables[arguments[0]] = 0;

        // Print statement, using string interpolation
        if (z[0] == "p")
            result += $"{arguments[0]} = {variables[arguments[0]]}\n";
        // Increment statement
        else if (z[0] == "i")
            variables[arguments[0]]++;
        // Decrement statement
        else if (z[0] == "d")
            if (variables[arguments[0]] > 0)
                variables[arguments[0]]--;
            else
                return false;
        else
        {
            // Get the line number to jump to
            var y = statements[z[0]];

            // Execute A ? B : C
            return Execute(y + 1, arguments) ? Execute(y + 2, arguments) : Execute(y + 3, arguments);
        }

        // If we reach this point, it's from a 'p', 'i' or 'd' statement which has succeeded
        return true;
    }
}

इसका उपयोग करने के लिए, बस क्लास को तुरंत टाइप करें और R()विधि को कॉल करें , उदाहरण के लिए:

string prindealText = new StreamReader("prindeal.txt").ReadToEnd();
Console.WriteLine(new P().R(prindealText));

3

आम लिस्प, 758 646 619

(progn(set-macro-character #\#(get-macro-character #\;))(setf(readtable-case *readtable*):invert)(#3=defun v(s)(if(boundp s)(eval s)0))(#3# i(s)(set s(1+ (v s))))(#3# d(s)(and(plusp(v s))(set s(1-(v s)))))(#3# p(s)(format t"~A = ~A~%"s(v s)))(defmacro a(n . p)`(#3#,(cadr n)(&rest g)(if,@p)))(#3# k(s)(typecase s(integer`(nth,(1- s)g))(symbol `',s)(t(list*(car s)(mapcar 'k(cdr s))))))(#3# r()(prog(l p q)$(setf p()l(make-string-input-stream(or(read-line()()())(return))))@(when(setf p(read l()()))(push p q)(go @))(if q(return(k(reverse q)))(go $))))(do ((x(r)(r)))((not x))(eval(if(eq(car x)'a)`(,@x,(r),(r),(r))x))))

इसे अंदर रखो file.lispऔर उदाहरण के लिए बुलाओ sbcl --script file.lisp; इनपुट को मानक इनपुट स्ट्रीम से पढ़ा जाता है।

यह संस्करण Prindeal के एक सुपरसेट को पार्स करता है : अधिक कठिनाइयों के बिना, आप Prindeal स्रोत से सभी कॉमन लिस्प तक पहुँच सकते हैं। मैं इसे इंट्रिप्टर की एक विशेषता मानता हूं ।

टिप्पणी संस्करण

;; copy-readtable is only used during development, so that I do not 
;; mess with my running environment. The real code starts with the
;; progn below, which is superfluous of course inside a let.
(let ((*readtable* (copy-readtable)))

  ;; I use PROGN in the golfed version so that I can have the whole
  ;; program as a unique tree. This allows me to define reader 
  ;; variables like #3=defun in order to gain a few bytes by writing
  ;; #3# instead of defun. Reader variables are removed in
  ;; this human-friendly version.
  (progn
    ;; Let # point to the same reader function as ;
    ;; Of course, ; is still usable as a comment delimiter
    (set-macro-character #\#
                         (get-macro-character #\;))

    ;; :invert does what is necessary to enable case-sensitive reading
    ;; and printing of symbols
    (setf (readtable-case *readtable*) :invert)

    ;; value of symbol, or zero
    (defun v(s)(if(boundp s)(eval s)0))

    ;; increment
    (defun i(s)(set s(1+ (v s))))

    ;; decrement
    (defun d(s)(and(plusp(v s))(set s(1-(v s)))))

    ;; print
    (defun p(s)(format t"~A = ~A~%"s(v s)))

    ;; alias: wrap an "if" inside a "defun".
    ;; YES, that means you can redefine ANY lisp function with "a" !
    ;; A safer version would properly intern symbols in a dedicated package.
    ;;
    ;; Notice the G variable.  We take advantage of the "unhygienic"
    ;; (what a bad adjective) nature of macros to create a context
    ;; where G is bound to the argument list. The same G is referenced
    ;; implicitely later.
    (defmacro a(n . p)`(defun,(cadr n)(&rest g)(if,@p)))

    ;; Canonicalize expressions:
    ;;
    ;; - if s is a symbol, return s quoted. All functions manipulate
    ;; symbols in order to allow the undeclared use of variables. With
    ;; symbols, we can check for boundness.
    ;;
    ;; - if s is an integer, then we are inside an alias definition. The
    ;; integer is replaced by an access to the s'th element of the
    ;; implicit argument list G using (nth (1- s) g). G will be bound
    ;; when the expressions is injected in the defun corresponding to
    ;; the alias, or else an error will be signaled: either because G
    ;; is unbound, or because you defined a variable named G which is
    ;; by construction not a list. Since we do not sanitize properly
    ;; the input, you could bind G globally to a list, but that would be
    ;; nasty.
    ;; 
    ;; - Finally, if s is a list, apply k to all but the first
    ;; elements of s.  The first element is a symbol but we do not
    ;; need to quote it because we want to call the function
    ;; associated with the symbol. Due to the Lisp-2-ness
    ;; of Common Lisp, functions and variables can coexist
    ;; with the same name.
    ;;
    (defun k(s)(typecase s
                 (integer`(nth,(1- s)g))
                 (symbol`',s)
                 (t(list*(car s)(mapcar #'k(cdr s))))))

    ;; Reader function
    (defun r()
      (prog (l ; current line, as an input-stream reading a string
             p ; current read form
             q ; whole line and return value, as a list
             )

         ;; PROG includes an implicit TAGBODY. Below, $ and @ are
         ;; labels for GO statements (gotos).

       $ (setf
          ;; emtpy p
          p ()

          ;; Read a whole line and if we do not fail, build an input
          ;; stream to read from it.
          l (make-string-input-stream
             (or (read-line()()()) ;; try to read a line,
                 (return)          ;; but return from prog if we reach
                                   ;; the end of file.
                 )))
       @ (when (setf p (read l()()))
           ;; Read a lisp expression, put it in p and if p is not nil
           ;; push it into q.  A nil could happen at the end of the
           ;; line or if someone (you know who) inserted an empty list
           ;; in the file being read.
           ;; 
           ;; Thanks to the readtable which now handles comments
           ;; and spaces for us, nothing needs to be done here to
           ;; preprocess the input.

           (push p q) (go @))

         ;; If we read an empty line, q can be nil. In this case, go
         ;; back to $ and read another line. If q is not nil, reverse
         ;; it (we pushed, remember), canonicalize it and return the
         ;; result.
         (if q (return(k(reverse q))) (go $)))
      )

    ;; Read/eval loop.  When reading "(a name)", we read the three
    ;; next lines and append them to the first so that it builds a
    ;; call the the alias definition macro a. Otherwise, just eval x.
    (do((x(r)(r))((not x))
      (eval (if (eq(car x'a))
                `(,@x,(r),(r),(r))
                x)))))

उदाहरण

~$ sbcl --script file.lisp < testfile

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

अगर हम बदलने के evalद्वारा printपढ़ा / eval पाश में है, तो हम देख सकते हैं कि मूल्यांकन किया जा रहा है:

(a 's (i '_) (d '_) (d '_)) 
(a 'f (d '_) (d '_) (d '_)) 
(a 'z (d (nth 0 g)) (z (nth 0 g)) (s)) 
(a 'n (z (nth 0 g)) (i (nth 0 g)) (s)) 
(a 'move (moveH (nth 0 g) (nth 1 g)) (move (nth 0 g) (nth 1 g)) (s)) 
(a 'moveH (d (nth 0 g)) (i (nth 1 g)) (f)) 
(a 'dupe (dupeH1 (nth 0 g) (nth 1 g) (nth 2 g))
   (dupe (nth 0 g) (nth 1 g) (nth 2 g)) (s)) 
(a 'dupeH1 (d (nth 0 g)) (dupeH2 (nth 1 g) (nth 2 g)) (f)) 
(a 'dupeH2 (i (nth 0 g)) (i (nth 1 g)) (s)) 
(a 'copy (z (nth 1 g)) (copyH (nth 0 g) (nth 1 g)) (s)) 
(a 'copyH (dupe (nth 0 g) (nth 1 g) '_copy) (move '_copy (nth 0 g)) (s)) 
(a 'addTo (copy (nth 1 g) '_add) (move '_add (nth 0 g)) (s)) 
(a 'add (z (nth 0 g)) (addH (nth 0 g) (nth 1 g) (nth 2 g)) (s)) 
(a 'addH (addTo (nth 0 g) (nth 1 g)) (addTo (nth 0 g) (nth 2 g)) (s)) 
(a 'mul (mulH1 (nth 0 g) (nth 1 g)) (mulH2 (nth 0 g) (nth 2 g)) (s)) 
(a 'mulH1 (z (nth 0 g)) (copy (nth 1 g) '_mul) (s)) 
(a 'mulH2 (mulH3 (nth 0 g) (nth 1 g)) (mulH2 (nth 0 g) (nth 1 g)) (s)) 
(a 'mulH3 (d '_mul) (addTo (nth 0 g) (nth 1 g)) (f)) 
(a 'mulBy (mul '_mulBy (nth 0 g) (nth 1 g)) (copy '_mulBy (nth 0 g)) (s)) 
(a 'pow (powH1 (nth 0 g) (nth 2 g)) (powH2 (nth 0 g) (nth 1 g)) (s)) 
(a 'powH1 (n (nth 0 g)) (copy (nth 1 g) '_pow) (s)) 
(a 'powH2 (powH3 (nth 0 g) (nth 1 g)) (powH2 (nth 0 g) (nth 1 g)) (s)) 
(a 'powH3 (d '_pow) (mulBy (nth 0 g) (nth 1 g)) (f)) 
(p 'A) 
(p 'B) 
(p 'C) 
(n 'A) 
(n 'B) 
(add 'C 'A 'B) 
(p '____) 
(p 'A) 
(p 'B) 
(p 'C) 
(add 'B 'A 'C) 
(p '____) 
(p 'A) 
(p 'B) 
(p 'C) 
(mul 'd 'B 'C) 
(p '____) 
(p 'd) 
(mulBy 'd 'B) 
(p '____) 
(p 'd) 
(d 'A) 
(mulBy 'd 'A) 
(p '____) 
(p 'd) 
(pow 'A 'C 'B) 
(p '____) 
(p 'A) 
(p 'B) 
(p 'C) 
(pow 'A 'B 'C) 
(p '____) 
(p 'A) 
(p 'B) 
(p 'C) 
(pow 'C 'A 'B) 
(p '____) 
(p 'A) 
(p 'B) 
(p 'C)

Macroexpansion

यदि हम निम्नलिखित उपनाम की परिभाषा चुनते हैं:

(a 'powH2 (powH3 (nth 0 g) (nth 1 g)) (powH2 (nth 0 g) (nth 1 g)) (s))

... हम एक चर के संदर्भ को देख सकते हैं जिसका नाम gलेक्सिकल स्कोप में कहीं नहीं है। लेकिन स्थूल विस्तार के बाद, यहां वास्तविक कोड का मूल्यांकन किया जा रहा है:

(defun powH2 (&rest g)
  (if (powH3 (nth 0 g) (nth 1 g))
      (powH2 (nth 0 g) (nth 1 g))
      (s))) 

अब, gफ़ंक्शन की तर्क सूची को परिभाषित किया जा रहा है।


2

पायथन 2, 486 बाइट्स

यह संदर्भ समाधान है जिसे मैंने और अधिक गोल्फ (वर्तमान में -98 बाइट्स) दिया है।

import sys;sys.setrecursionlimit(2000)
def r(s):
 n=s[0]
 if n in A:f=lambda i:r([s[int(t)]if'0'<t[0]<':'else t for t in A[n][i]]);return f(1+(f(0)or 0))
 k=s[1]
 if'i'<n:print k,'=',V.get(k,0)
 elif'd'<n:V[k]=-~V[k]if k in V else 1
 elif'a'<n:
    if~-(k in V)or V[k]<1:return 1
    V[k]-=1
 else:A[k]=s[2:]
A={};V={};c=filter(bool,([l,l[:l.find('#')]]['#'in l]for l in input().split('\n')))
while c:
 s=c[0].split();c=c[1:]
 if'a'!=s[0]:r(s)
 else:r(['a',s[1]]+map(str.split,c[:3]));c=c[3:]

परिवर्तन (जो मुझे याद है):

  • स्वचालित बूलियन-पूर्णांक रूपांतरण ([l,l[:l.find('#')]]['#'in l] )।
  • एक बयान में सेट या वेतन वृद्धि (V[k]=-~V[k]if k in V else 1 )
  • अधिक अभिव्यक्तियों के लिए अधिक उपनाम (k=s[1] )
  • इसके बजाय इनपुट सूची को साफ़ करते हुए मुख्य लूप में कोई काउंटर नहीं
  • print स्वचालित रूप से रिक्त स्थान जोड़ना (print k,'=',V.get(k,0) )
  • 1-9 अंकों की जाँच'0'<t[0]<':' )
  • rबचाने के लिए चारों ओर के रिटर्न मानों को फ़्लिप करनाreturn रों
  • टुकड़ा करने की क्रिया और विभाजन को हटाना ( map(str.split,c[:3])))

1

पायथन 3, 1322 बाइट्स

golfed:

import re,sys;sys.setrecursionlimit(2000);F,L=filter,list
class P:
 N,O,F=0,{},{}
 def __init__(S,c):
  S.B,S.E={"p":S.P,"i":S.I,"d":S.D,"a":S.L},dict(enumerate(F(None,[i.split('#')[0].rstrip()for i in c.splitlines()])))
  while S.N in S.E:S.X(S.E[S.N])
 def V(S, v, y, z=0):
  if re.match("[\w_][\d\w_]*",v):
   if not v in y:
    if z is not None:y[v]=z
    else:return False
   return True
  return False
 def A(S):S.N+=1
 def P(S,v):
  if S.V(v,S.O):print("{0} = {1}".format(v, S.O[v]));return True
  return False
 def I(S,v):
  if S.V(v, S.O):S.O[v]+=1;return True
  return False
 def D(S,v):
  if S.V(v,S.O)and S.O[v]>0:S.O[v]-=1;return True
  return False
 def L(S,v):
  e=[]
  if S.V(v,S.F,e):
   for i in range(3):S.A();e.append(S.E[S.N].lstrip())
   return True
  return False
 def C(S,c,v):
  def R(Z,v):
   for i in re.findall("\s(\d+)", Z):Z=Z.replace(" %s"%i," %s"%v[int(i)-1])
   return Z
  Q,m,f=map(lambda l:R(l,v),S.F[c])
  if S.X(Q,False):return S.X(m,False)
  return S.X(f,False)
 def X(S,Z,C=True):
  u=re.match("\s?([\w_][\d\w_]*)\s?([\w_][\d\w ]*)?",Z)
  if u:
   c,v=map(lambda i:''if i is None else i,u.groups());v=L(F(None,v.split(' ')))
   if S.V(c,S.F,None):
    T=S.C(c, v)
    if C:S.A()
   elif S.V(c,S.B,None):
    T=S.B[c](*v)
    if C:S.A()
   else:return False
   return T
  return False

Ungolfed:

import re

class Prindeal:
    iline = 0
    local = {}
    udef = {}
    content  = {}

    def __init__(self, c):
        self.built = {
            "p": self.print,
            "i": self.increment,
            "d": self.decrement,
            "a": self.alias,
        }
        self.content = dict(enumerate(filter(None, [i.split('#')[0].rstrip()for i in c.splitlines()])))
        while self.iline in self.content:
            self.execute_line(self.content[self.iline])

    def validate_name(self, varname, stack, default=0):
        if re.match("[\w_][\d\w_]*", varname):
            if not varname in stack:
                if default is not None:
                    stack[varname] = default
                else:
                    return False
            return True
        return False

    def advance_stack(self):
        self.iline += 1

    def print(self, varname):
        if self.validate_name(varname, self.local):
            print("{0} = {1}".format(varname, self.local[varname]))
            return True
        return False

    def increment(self, varname):
        if self.validate_name(varname, self.local):
            self.local[varname] += 1
            return True
        return False

    def decrement(self, varname):
        if self.validate_name(varname, self.local) and self.local[varname] > 0:
            self.local[varname] -= 1
            return True
        return False

    def alias(self, aliasname):
        indexed_lines = []
        if self.validate_name(aliasname, self.udef, indexed_lines):
            for i in range(3):
                self.advance_stack()
                indexed_lines.append(self.content[self.iline].lstrip())
            return True
        return False

    def execute_alias(self, cmd, variables):
        def parse_args(line, variables):
            for i in re.findall("\s(\d+)", line):
                line = line.replace(" %s" % i, " %s" % variables[int(i) - 1])
            return line
        init, success, failure = map(lambda l: parse_args(l, variables), self.udef[cmd])
        if self.execute_line(init, False):
            return self.execute_line(success, False)
        return self.execute_line(failure, False)

    def execute_line(self, line, cont=True):
        valid_execution = re.match("\s?([\w_][\d\w_]*)\s?([\w_][\d\w ]*)?", line)
        if valid_execution:
            cmd, variables = map(lambda i: '' if i is None else i, valid_execution.groups())
            variables = list(filter(None, variables.split(' ')))
            if self.validate_name(cmd, self.udef, None):
                temp = self.execute_alias(cmd, variables)
                if cont:
                    self.advance_stack()
            elif self.validate_name(cmd, self.built, None):
                temp = self.built[cmd](*variables)
                if cont:
                    self.advance_stack()
            else:
                return False
            return temp
        return False

उपयोग:

P(c)

cपाठ सामग्री कहां है

उदाहरण:

सिंगल-लाइन स्ट्रिंग्स स्वीकार किए जाते हैं:

  • P("p cat")
  • P("p dog\ni dog\np dog")

बहु-पंक्ति वाले तार भी स्वीकार किए जाते हैं:

P("""
p dog
i dog
p dog
""")

या:

P("""p dog
i dog
p dog""")

आदि।

टिप्पणियाँ:

यह सभी परीक्षण मामलों के लिए सही ढंग से काम करता है, लेकिन पुनरावर्ती सीमा तक पहुंचता है:

pow C A B   #C = A ^ B = 9 ^ 3 = 729

इसलिए sys.setrecursionlimit(2000)


1
यह कुछ बाइट्स का उपयोग करेगा, लेकिन क्या आप pys alias के साथ इसे ठीक से काम करने के लिए sys.setrecursionlimit () का उपयोग नहीं कर सकते हैं?
कॉर्विन

मैं कर सकता था, लेकिन ओपी ने कहा कि पायथन (जिसकी पुनरावृत्ति सीमा है) जैसी भाषाओं को इस रूप में स्वीकार किया जाता है। हालांकि, ओपी द्वारा अनुरोध किए जाने पर मैं इसे जोड़ दूंगा। @ कॉरविन
जैच गेट्स

काफी उचित। याद किया कि कल्पना में। @ZachGates
कॉर्विन

1

पायथन - 695 688 बाइट्स

def p(v):print v,"=",w.get(v,0)
def i(v):w[v]=w.get(v,0)+1
def d(v):
 if v in w:
<TAB>w[v]-=1
<TAB>if not w[v]:del w[v]
 else:return 1
def a(n,b,d,h):
 def g(*a):
<TAB>i=1;f=b;s=d;t=h
<TAB>for v in a:v=q+v+q;k=q+j(i)+q;f=c(f,k,v);s=c(s,k,v);t=c(t,k,v);i+=1
<TAB>y=u(t,e)if u(f,e)else u(s,e);i=1;return y
 e[n]=g
q="'";w=x={};u=eval;e={'a':a,'d':d,'i':i,'p':p};import sys;l=sys.stdin.readlines();r="";j=str;c=j.replace;sys.setrecursionlimit(2000)
for h in l:
 h = h.strip()
 if not h:continue
 l = h.split();f=l[0];n=f+"("
 if "#" in f:continue
 for g in l[1:]:
<TAB>b=g.find("#")+1
<TAB>if b:g=g[:b-1]
<TAB>if g:n+="'%s',"%g
<TAB>if b:break
 if x:x-=1;d+='"%s)",'%n
 else:x=(f=="a")*3;d=n
 if not x:d+=")\n";r+=d
exec r in e

<TAB> एक शाब्दिक टैब वर्ण है।


1

सी ++, 1111 बाइट्स

यह एक सी ++ है - मुहावरेदार के रूप में मैं इसे बना सकता हूं।
इसका मतलब है कि यह अधिक C ++ - ish और कम C-ish बनाता है।
इसका मतलब यह भी है कि यह बराबर सी प्रोग्राम से बड़ा है।
मुझे लगता है कि C ++ प्रतिद्वंद्वियों जावा मानक लाइब्रेरी के लिए।
यह VS2013 और g ++ 4.9.2 के साथ संकलित है (-std = c ++ 11 के साथ)

#include<array>
#include<iostream>
#include<map>
#include<regex>
#include<sstream>
#include<stack>
#define B std::
#define a first
#define b second
#define c(s);else if(x.a==s)
#define d(n)B getline(B cin,r##n)
#define e(n)r##n=B regex_replace(r##n,q,"$1");
#define f(n)do{d(n);e(n)}while(r##n.empty());
#define g B string
#define h B istream_iterator<g>
#define i p.top().a
#define j p.empty()
#define k B pair
#define u continue;
#define w B back_inserter
typedef B vector<g>s;typedef B array<g,3>A;typedef k<k<long,A>,s>t;B map<g,A>m;B map<g,long>n;B stack<t>p;B regex q("^ *(.*?) *(#.*)?$");int main(){g r0,r1,r2,r3;while(d(0)){e(0)if(r0.empty())u p.push(t{{0,{{r0,"",""}}},{}});bool z;while(!j){k<g,s>x;B istringstream ss(i.b[i.a]);ss>>x.a;B copy(h(ss),h(),w(x.b));s o;B transform(B begin(x.b),B end(x.b),w(o),[](g y){int v=atoi(y.c_str());return v>0?p.top().b[v-1]:y;});z=true;if(0)c("")c("p")B cout<<o[0]<<" = "<<n[o[0]]<<B endl c("i")n[o[0]]++c("d")n[o[0]]-=(z=n[o[0]])c("a"){f(1)f(2)f(3)m.insert(B make_pair(o[0],A{{r1,r2,r3}}));}else{p.push(t{{0,m[x.a]},o});u}while(!j&&i.a)p.pop();if(!j)i.a+=1+!z;}}}

नीचे मूल है। अगर कोई एक ही समय में इसे और अधिक मुहावरेदार और छोटा बनाने का तरीका सोच सकता है तो कृपया मुझे बताएं।

#include <array>
#include <iostream>
#include <map>
#include <regex>
#include <sstream>
#include <stack>

typedef std::vector<std::string> List;
typedef std::pair<std::string, List> Statement;
typedef std::array<std::string, 3> Alias;
typedef std::pair<long, Alias> IndexedAlias;
typedef std::pair<IndexedAlias, List> Item;

std::map<std::string, Alias> aliases;
std::map<std::string, long> variables;
std::stack<Item> stack;
std::regex re("^ *(.*?) *(#.*)?$");

int main()
{
    std::string line, line1, line2, line3;
    while (std::getline(std::cin, line)) // control-Z to exit
    {
        line = std::regex_replace(line, re, "$1");
        if (line.empty()) continue;
        stack.push(Item{ { 0, { { line, "", "" } } }, {} });

        bool flag;
        while (!stack.empty())
        {
            Statement statement;
            std::istringstream ss(stack.top().first.second[stack.top().first.first]);
            ss >> statement.first;
            std::copy(std::istream_iterator<std::string>(ss), std::istream_iterator<std::string>(), std::back_inserter(statement.second));

            List arguments;
            std::transform(std::begin(statement.second), std::end(statement.second), std::back_inserter(arguments),
                [](std::string arg){ int i = atoi(arg.c_str()); return i > 0 ? stack.top().second[i - 1] : arg; });

            flag = true;
            if (statement.first == "")
                ;
            else if (statement.first == "p")
                std::cout << arguments[0] << " = " << variables[arguments[0]] << std::endl;
            else if (statement.first == "i")
                variables[arguments[0]]++;
            else if (statement.first == "d")
                variables[arguments[0]] -= (flag = variables[arguments[0]]);
            else if (statement.first == "a")
            {
                do { std::getline(std::cin, line1); line1 = std::regex_replace(line1, re, "$1"); } while (line1.empty());
                do { std::getline(std::cin, line2); line2 = std::regex_replace(line2, re, "$1"); } while (line2.empty());
                do { std::getline(std::cin, line3); line3 = std::regex_replace(line3, re, "$1"); } while (line3.empty());
                aliases.insert(std::make_pair(arguments[0], Alias{ { line1, line2, line3 } }));
            }
            else
            {
                stack.push(Item{ { 0, aliases[statement.first] }, arguments });
                continue;
            }

            while (!stack.empty() && stack.top().first.first) stack.pop();
            if (!stack.empty()) stack.top().first.first += 1 + !flag;
        }
    }

    std::cout << "-- Variables --" << std::endl;
    std::transform(std::begin(variables), std::end(variables), std::ostream_iterator<std::string>(std::cout, "\n"),
        [](std::map<std::string, long>::value_type pair){ std::ostringstream ss; ss << pair.first << " = " << pair.second; return ss.str(); });
    std::cout << "-- Aliases --" << std::endl;
    std::transform(std::begin(aliases), std::end(aliases), std::ostream_iterator<std::string>(std::cout, "\n"),
        [](std::map<std::string, Alias>::value_type pair){ std::ostringstream ss; ss << pair.first << " = [1]:" << pair.second[0] << " [2]:" << pair.second[1] << " [3]:" << pair.second[1]; return ss.str(); });
    std::cout << "---------------" << std::endl;

    return 0;
}

0

हास्केल, 1009

मैंने इसे गोल्फ में करने की पूरी कोशिश की; मेरे अ-कोडित कोड में 3,000 से अधिक वर्ण शामिल थे। इस बिंदु पर मुझे याद नहीं आ रहा है कि सभी कार्य क्या कर रहे हैं, इसलिए इसे और अधिक अनुमान लगाने का मतलब है कि यह क्या टूट जाएगा और क्या नहीं होगा।

import qualified Data.Map as M
import Control.Monad.State.Lazy
import Data.List
type A=M.Map String
data P=P(A Int)(A([String]->StateT P IO Int))
a f=evalStateT f(P M.empty$M.fromList[("i",\(b:_)->(+1)%b),("d",\(b:_)->pred%b),("p",\(b:_)->i b>>= \v->liftIO(putStrLn$b++"="++show v)>>q 1)])
e(k:l)=do{(P v a)<-get;put.P v$M.insert k(m l)a;q 1}
g t s f= \a->t a>>= \b->if b>0then s a else f a
f%k=f<$>i k>>= \v->if v<0then k#0>>q 0else k#v>>q 1
i k=get>>= \(P v _)->q$M.findWithDefault 0 k v
k#v=get>>= \(P b a)->put$P(M.insert k v b)a
l k=get>>= \(P _ a)->q$a M.!k
f s=let(f:a)=r s in($a)<$>l f>>=id
m(t:s:f:_)=g(k t)(k s)(k f)
k s=let(f:b)=r s in\a->($(map((\y z->if all(\c->c>'/'&&c<':')z then y!!(read z-1)else z)a)b))<$>l f>>=id
n=dropWhileEnd(==' ').takeWhile(not.(=='#')).dropWhile(==' ')
o[]=[]
o(l:ls)|(head.r$l)=="a"=(l:take 3 ls):(o$drop 3 ls)|1>0=[l]:o ls
p s|length s>1=e$(n.tail.head$s):tail s|1>0=f.head$s
q=return
main=join$a.(\s->mapM_ p(o.filter(not.null).map n.lines$s))<$>getContents
r=words
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.