SAS मैक्रो चर को हल करें


13

एसएएस प्रोग्रामिंग भाषा 1966 तक किसी बेकार, पुरातन भाषा डेटिंग वापस प्रयोग में आज भी कर रही है। मूल संकलक पीएल / I में लिखा गया था , और वास्तव में PL / I से बहुत अधिक सिंटैक्स प्राप्त होता है। एसएएस में एक प्रीप्रोसेसर मैक्रो भाषा भी है जो पीएल / आई से भी प्राप्त होती है। इस चुनौती में, आप एसएएस मैक्रो भाषा के कुछ सरल तत्वों की व्याख्या करेंगे।

एसएएस मैक्रो भाषा में, %letकीवर्ड का उपयोग करके मैक्रो चर को परिभाषित किया जाता है और लॉग के लिए मुद्रण के साथ किया जाता है %put। कथन अर्धविराम के साथ समाप्त होते हैं। यहाँ कुछ उदाहरण हैं:

%let x = 5;
%let cool_beans =Cool beans;
%let what123=46.lel"{)-++;

मैक्रो चर नाम केस असंवेदनशील हैं और हमेशा नियमित अभिव्यक्ति से मेल खाते हैं /[a-z_][a-z0-9_]*/i। इस चुनौती के प्रयोजनों के लिए, हम निम्नलिखित कहेंगे:

  • मैक्रो चर केवल प्रिंट योग्य ASCII वर्ण की पूरी तरह से मिलकर मान हो सकते हैं को छोड़कर ; , &और%
  • मूल्यों में कोई अग्रणी या अनुगामी स्थान नहीं होगा
  • मान 255 वर्णों से अधिक लंबे नहीं होंगे
  • मान रिक्त हो सकते हैं
  • मूल्यों में ब्रैकेट और उद्धरण बेजोड़ हो सकते हैं
  • बयान =में पहले और बाद में किसी भी स्थान की मात्रा हो सकती है %letऔर इस स्थान को अनदेखा किया जाना चाहिए
  • बयान ;में टर्मिनल से पहले अंतरिक्ष की कोई भी राशि हो सकती है %letऔर इस स्थान की इसी तरह अनदेखी की जानी चाहिए

जब एक मैक्रो वैरिएबल कहा जाता है, तो हम कहते हैं कि यह "मूल्य" को हल करता है। मैक्रो वैरिएबल को हल करके तैयार किया गया है &। एक वैकल्पिक अनुगामी .है जो पहचानकर्ता के अंत को दर्शाता है। उदाहरण के लिए,

%put The value of x is &X..;

The value of x is 5.लॉग को लिखता है। ध्यान दें कि दो अवधियों की आवश्यकता होती है क्योंकि एक एकल अवधि की खपत &X.और संकल्प द्वारा की जाएगी 5। यह भी ध्यान दें कि भले ही हमने xलोअरकेस में परिभाषित किया है, &Xयह वैसा ही है &xक्योंकि मैक्रो चर नाम असंवेदनशील हैं।

यहाँ यह मुश्किल हो जाता है। &चर को हल करने के लिए एकाधिक s को एक साथ मारा जा सकता है, और &एक ही समय में नेस्टिंग के समान स्तर पर हल किया जा सकता है। उदाहरण के लिए,

%let i = 1;
%let coolbeans1 = broseph;
%let broseph = 5;

%put &&coolbeans&i;  /* Prints broseph */
%put &&&coolbeans&i; /* Prints 5 */

अंतरतम &संकल्प पहले, और संकल्प बाहर की ओर जारी है। चर नाम मिलान लालच से किया जाता है। दूसरे %putकथन में, प्रोसेसर निम्नलिखित कदम उठाता है:

  1. &iकरने के लिए हल करता है 1, और अग्रणी अंतर &भस्म है, हमें दे रही है&&coolbeans1
  2. &coolbeans1brosephहमें देने का संकल्प करता है&broseph
  3. &brosephको हल करता है 5

यदि अनुगामी .s हैं, तो केवल एक ही .संकल्‍प में खपाया जाता है, भले ही एकाधिक &s हों।

कार्य

1 और 10 %letस्टेटमेंट के बीच दिए गए नए कथनों और एक स्टेटमेंट को देखते हुए %put, स्टेटमेंट के परिणाम को प्रिंट या वापस करें %put। इनपुट को किसी भी मानक तरीके से स्वीकार किया जा सकता है।

आप मान सकते हैं कि इनपुट हमेशा मान्य होगा और यह %letकथन कथन को आगे बढ़ाएगा %put। जिन वेरिएबल्स को परिभाषित किया गया है, उन्हें बाद के %letकथनों में फिर से परिभाषित नहीं किया जाएगा ।

यदि वास्तव में एसएएस में चलाया जाता है, तो चर के समाधान के लिए कोई समस्या नहीं होगी, जो कि चर में मौजूद नहीं है और ऊपर वर्णित सभी चीज़ों को वाक्यविन्यास रूप से सही किया जाएगा।

उदाहरण

  1. इनपुट:

    %let dude=stuff;
    %let stuff=bEaNs;
    %put &&dude..;
    

    आउटपुट:

    bEaNs.
    
  2. इनपुट:

    %let __6 = 6__;
    %put __6&__6;
    

    आउटपुट:

    __66__
    
  3. इनपुट:

    %let i=1;
    %let hOt1Dog = BUNS;
    %put &&HoT&i.Dog are FUNS&i!");
    

    आउटपुट:

    BUNS are FUNS1!")
    
  4. इनपुट:

    %let x = {*':TT7d;
    %put SAS is weird.;
    

    आउटपुट:

    SAS is weird.
    
  5. इनपुट:

    %let var1   =  Hm?;
    %let var11 = var1;
    %let UNUSED = ;
    %put &&var11.....;
    

    आउटपुट:

    Hm?....
    

    ध्यान दें कि नाम मिलान के बाद से &&var11मैच var11लालची है। अगर वहाँ एक था ., यानी &&var1.1, तो var1मिलान किया जाएगा और अतिरिक्त 1 किसी भी नाम का हिस्सा नहीं होगा।

यह कोड गोल्फ है, इसलिए बाइट्स जीत में सबसे छोटा समाधान है!


टेस्ट केस 1 से आउटपुट की अवधि कैसे होती है? &stuff.अवधि नहीं निकालना चाहिए ?
GamrCorps

@GamrCorps मुझे निर्दिष्ट करना चाहिए: संकल्प में केवल एक एकल अनुगामी अवधि का उपभोग किया जाता है।
एलेक्स ए।

@GamrCorps को निर्दिष्ट करने के लिए संपादित किया गया और इसे एक परीक्षण मामले के रूप में जोड़ा गया।
एलेक्स ए।

तो &&&&&&&&&a......................क्या अब भी केवल एक अवधि को हटाया जाएगा?
GamrCorps

@GamrCorps हां।
एलेक्स ए।

जवाबों:


1

पायथन 3 , 354 341 336 बाइट्स

import re
S=re.sub
def f(x):
	r=x.splitlines();C=r[-1].strip('%put ');D=0
	while D!=C:
		D=C
		for a in sorted([l.strip('%let ').replace(" ","").split(';')[0].split('=')for l in r[:-1]],key=lambda y:-len(y[0])):
			s=1
			while s:C,s=re.subn('&'+a[0]+'(\.?)',a[1]+'😍\\1',S('😍+\.([^\.])','\\1',C),0,re.I)
	return S('😍+\.?','',C)

इसे ऑनलाइन आज़माएं!

संपादित करें: कुछ आसान छोटा

संपादित करें: [:: - 1] (5 बाइट्स) के बजाय -लेन (...) को उल्टा करके, जोनाथन फ्रीच को धन्यवाद!

Ungolfed

import re
S=re.sub # new name for the function re.sub()
def f(x):
    r=x.splitlines() # input string to list of rows
    C=r[-1].strip('%put ') # get the string to put (from the last row)
    D=0
    while(D!=C): # iterate until the result does not change
        D=C
        for a in                                                                                                                    : # iterate over the list of variables
                 sorted(                                                                          ,key=lambda y:len(y[0]),reverse=1) # sort list for greediness by decreasing var.name lengths
                        [l.strip('%let ') # cut the 'let' keyword
                                         .replace(" ","") # erase spaces
                                                         .split(';')[0] # cut parts after ';'
                                                                       .split('=') # create [variable_name,value] list
                                                                                  for l in r[:-1]] # for each row but last
            s=1
            while(s): # iterate until the result does not change
                C,s=re.subn( # substitute
                            '&'+a[0]+'(\.?)', # &varname. or &varname
                                                 a[1]+'😍\\1', # to value😍. or value😍
                                                              S('😍+\.([^\.])','\\1',C), # in the string we can get from C erasing (😍's)(.) sequences if the next char is not .
                                                                                        0,re.I) # substituting is case insensitive
    return S('😍+\.?','',C) # erase smileys and one .

मैं पायथन टिप्स पेज पर बहुत कुछ लेने का सुझाव दूंगा । गैर-यौगिक विवरण संगति ( ;), कोष्ठक में कमी ( if(...)-> if ...) और सूची संचालन ( ,reverse=1-> [::-1]) जैसे तुच्छ अनुकूलन कुछ बाइट्स को आसानी से बचा सकते हैं।
जोनाथन फ्रीच

धन्यवाद! मैंने इसे पहले पढ़ा है, लेकिन यह बहुत समय पहले था, और मैं कुछ चालें भूल गया।
9

आपका स्वागत है। len(y[0]))[::-1]हो सकता है -len(y[0]))
जोनाथन फ्रीच
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.