एक दो आयामी वाक्यविन्यास को पार्स करें


25

पृष्ठभूमि

एलिस और बॉब हर एक पीपीसीजी चुनौती को जीतने के लिए एक गोल्फ भाषा का निर्माण कर रहे हैं। ऐलिस दो आयामी भाषा बनाना चाहता है, जैसे> <>, लेकिन बॉब जे में एक उपसर्ग-इन्फिक्स सिंटैक्स पसंद करता है जैसे कि एक समझौता के रूप में, वे दो आयामी प्रीफिक्स-इन्फिक्स भाषा बनाने का निर्णय लेते हैं। पार्सर लिखने के लिए एक दर्द है, और उन्हें आपकी मदद की ज़रूरत है!

सिंटेक्स विनिर्देशन

ऐलिस और बॉब की भाषा में, चर होते हैं , जो निचले एस्केसी अक्षरों द्वारा दर्शाए जाते हैं a-z, और फ़ंक्शन , जो अपरकेस एएससीआईआई पत्रों द्वारा दर्शाए जाते हैं A-Z। एक फ़ंक्शन को एक या दो तर्कों के साथ लागू किया जा सकता है। एक प्रोग्राम अक्षरों a-zA-Zऔर स्थानों का एक आयताकार ग्रिड है , और ऊपरी बाएं कोने में एक स्थान नहीं होना चाहिए। यह एक वैध कार्यक्रम का एक उदाहरण है:

F Gy
H   
R x 

जब कार्यक्रम पार्स किया गया है, यह एक सी शैली भाषा (सी, जावा, पायथन ...) प्रारूप में एक अक्षर चर और समारोह कॉल युक्त की अभिव्यक्ति के रूप में तब्दील है <func>(<arg>)या <func>(<arg1>,<arg2>)। उदाहरण के लिए, उपरोक्त कार्यक्रम इस अभिव्यक्ति का परिणाम है:

F(H(R(x)),G(x,y))

पार्सिंग प्रक्रिया का विवरण इस प्रकार है:

  • रिक्त स्थान केवल भराव हैं, इसलिए वे पार्स नहीं हैं।
  • प्रत्येक चर a-zहमेशा की तरह अपने आप में पार्स होता है।
  • प्रत्येक फ़ंक्शन A-Zको फ़ंक्शन कॉल के रूप में पार्स किया जाता है। इसके तर्क इसके नीचे और ग्रिड में इसके दाईं ओर सबसे निकटतम भाव हैं, इस क्रम में। यदि इनमें से केवल एक ही मौजूद है, तो इसे एकमात्र तर्क के रूप में दिया गया है। आप मान सकते हैं कि सभी कार्यों में ग्रिड में कम से कम एक तर्क है।

उपरोक्त उदाहरण में, चर xऔर yस्वयं के रूप में पार्स किए गए हैं। फ़ंक्शन के Rनीचे और xइसके दाईं ओर कुछ भी नहीं है, इसलिए इसे एक-तर्क आह्वान के रूप में पार्स किया गया है R(x)। इसी तरह, इसे नीचे के Hरूप में पार्स H(R(x))किया Rगया है। फ़ंक्शन Gके xनीचे और yइसके दाईं ओर है, इसलिए इसे के रूप में पार्स किया गया है G(x,y), और इसी तरह के लिए F। शीर्ष बाएं कोने में पार्स की गई अभिव्यक्ति पार्सिंग प्रक्रिया का परिणाम है।

इनपुट और आउटपुट

आपका इनपुट वर्णों का एक गैर-रिक्त आयताकार सरणी है। यह हमेशा ऐलिस और बॉब की भाषा में एक मान्य कार्यक्रम होगा, लेकिन इसमें ऐसे भाव हो सकते हैं जो आउटपुट में उपयोग नहीं किए जाते हैं। उपरोक्त प्रक्रिया के परिणामस्वरूप आपका आउटपुट पार्स अभिव्यक्ति होगी।

नियम और स्कोरिंग

आप किसी फंक्शन का पूरा प्रोग्राम लिख सकते हैं। सबसे कम बाइट गिनती जीतता है, और मानक खामियों को रोक दिया जाता है।

परीक्षण के मामलों

ये प्रारूप में दिए गए हैं grid <newline> expression, ---मामलों के बीच हाइफ़न के साथ । एसई प्रारूप कुछ लाइनों को खाली छोड़ देता है, लेकिन उन्हें रिक्त स्थान से भरा होना चाहिए।

x
x
---
x y
z  
x
---
Fx
F(x)
---
Fx
y 
F(y,x)
---
ABu
A(B(u))
---
G
H
k
G(H(k))
---
ABCA
x xs
 DFk
A(x,B(D(F(k)),C(x,A(s))))
---
A  B  

C  D x
A(C(D(x)),B(D(x)))
---
RT Hq 
I xR k
R(I(x),T(H(R(k),q)))
---
A A  A a 
 S A  b  
B  C   Dx
d X  u f 
A(B(d,C(D(f,x))),A(X(u),A(u,a)))

क्या कोई आउटपुट (A (B (D x)) (C (D x)))उपयुक्त होगा या क्या प्रारूप तय किया गया है?
coredump

1
@coredump इस चुनौती में, आउटपुट स्वरूप सख्त है; ऐलिस और बॉब सीधे पार्स अभिव्यक्ति का उपयोग करने में सक्षम होना चाहते हैं।
ज़गरब

भाषा का "इनफ़िक्स" भाग कहाँ है? मैं केवल उपसर्ग देखता हूं।
पाओलो एबरमन

6
क्या आप वास्तव में इस वाक्य रचना के साथ एक भाषा बना सकते हैं? :)
मार्टिन एंडर

4
अनुवर्ती चुनौती: इस सिंटैक्स के लिए एक मेटा-गोल्फर लिखें (एक अभिव्यक्ति ट्री, इसके अनुरूप सबसे छोटा ग्रिड ढूंढें)। अतिरिक्त कठिनाई के लिए, कम्यूटेटिव और गैर-कम्यूटेटिव फ़ंक्शन के बीच अंतर करें।
मार्टिन एंडर

जवाबों:


8

CJam, 67 62 60 58 57 54 बाइट्स

4 बाइट बचाने के लिए डेनिस के लिए धन्यवाद।

{:Gsc_32&{"()"[GGz2{1m<_{S#}#>W<\}*z]{},{J}%',**+}|}:J

यह एक नामित ब्लॉक (फ़ंक्शन) को परिभाषित करता है Jऔर इसे स्टैक पर छोड़ देता है। फ़ंक्शन स्वयं स्टैक पर स्ट्रिंग्स की एक सरणी की अपेक्षा करता है, जो इनपुट ग्रिड का प्रतिनिधित्व करता है, और इसके अनुरूप वांछित स्ट्रिंग को छोड़ देता है।

इसका परीक्षण यहां करें।

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

व्याख्या

समाधान बेशक पुनरावर्ती है और धीरे-धीरे स्ट्रिंग का निर्माण करता है।

{
  :G       e#  Store the current grid in G.
  sc       e#  Convert the grid to a string, flattening it, then to a character, which
           e#  discards everything but the first character. This is a golfed 0=0=.
           e#  This character will either be an upper-case letter (function) or a lower-
           e#  case letter (variable).
  _32&     e#  Make a copy of the character and take bitwise AND with 32. This gives a
           e#  NULL character for functions and a space for variables.
  {        e#  If the result is falsy... (i.e. NULL, i.e. we have a function)
    "()"   e#   Push parentheses for later use.
    [      e#   Remember the current stack depth.
    GGz    e#   Push an array which contains the grid and its transpose.
    2{     e#   Run this block twice... (it will be applied once to each grid)
      1m<  e#    Rotate the rows. This has two effects: a) It removes the first row
           e#    from the front such that we can go looking for the next non-space
           e#    character down the first column from the start. b) It places a row
           e#    at the end which we know doesn't start with a space, which acts as
           e#    a guard in case there are no further letters below the current one.
      _    e#    Duplicate this grid.
      {    e#    Find the first index where this block yields something truthy...
        S# e#     Find the index of the first space in the current row. If the row
           e#     starts with a space, this is 0, i.e. falsy and the search continues.
           e#     If there is a space in any later position, that will be positive and
           e#     truthy, so this index gets returned. If there is no space at all,
           e#     the result is -1 which is also truthy and ends the search.
      }#        
      >    e#     Discard all lines up to (but not including) the found index.
      W<   e#     Discard the guard row at the end.
      \    e#     Swap the grids so that the next pass processes the other grid.
    }*       
    z      e#    Transpose the second grid back to its original orientation.
    ]      e#    Wrap both processed grids in an array.
    {},    e#    Remove a grid if it's empty.
    {J}/   e#    For each remaining grid, call J recursively.
    ',*    e#    Join the grids with commas if there are still two of them.
    *      e#    Wrap this string in the parentheses below on the stack.
    +      e#    Prepend the function name.
  }|
}:J

5

पायथन 2, 227 223 192 182 179 177 बाइट्स

def r(i,y=0,x=0):
 c=i[y][x];z=[]
 for t in"pq":
    p=q=0
    try:
     while" "==i[y+p][x+q]or 1>p+q:exec t+"+=1"
     z+=[r(i,y+p,x+q)]
    except:1
 return c+"(%s)"%",".join(z)*c.isupper()

(चार रिक्त स्थान वास्तव में टैब हैं)

आर के पहले तर्क के रूप में पात्रों की 2d सूची लेता है।


5

पायथ, 97 बाइट्स

D:TkdI}p@@QTkGR)=Z0p\(V2JK0W|q\ @@Q=b+TJ=H+kK!+JK=J+NJ=K+!NK)I!|gblQgHl@Q0p*Z\,:bH+=Z1d))p\);:000

मेरे भगवान को बनाने में लंबा समय लगा (लगभग 5/6 घंटे?)। पायथ वास्तव में इसके लिए डिज़ाइन नहीं किया गया था ...

इसे यहाँ आज़माएँ ।

व्याख्या के साथ-साथ अजगर के समकक्ष प्रयास करें

Q = literal_eval(input())

def at_slice(T,k,d):
  if Pprint(Q[T][k]) in "abcdefghijklmnopqrstuvwxyz": return 
  Z = 0
  Pprint("(")
  for N in range(2):
    J=K=0
    while " "==Q[assign('b',T+J)][assign('H',k+K)] or not J+K:
      J+=N
      K+=not N
    if not (b>=len(Q) or H>=len(Q[0])):
      Pprint(Z*",")
      at_slice(b,H,assign('Z',1)+d)
   Pprint(")")
at_slice(0,0,0)

जहां फ़ंक्शन Pprintऔर assignवे जो दिए गए हैं, उन्हें वापस करें।


बहुत कुछ। ऐसा वाह।
Addison Crump

5

हास्केल, 124 122 120 119 बाइट्स

r@((c:_):_)#g|c>'_'=[c]|c<'!'=g%r|1<2=c:'(':(tail%r)!(map tail%r)++")"
_#_=""
g%r=g r#g
a!b=a++[','|a>"",b>""]++b
(#id)

प्रयोग उदाहरण: (#id) ["RT Hq ","I xR k"]-> "R(I(x),T(H(R(k),q)))"

यह कैसे काम करता है: इनपुट ग्रिड के अलावा r, फ़ंक्शन #एक फ़ंक्शन gको एक तर्क के रूप में लेता है जो कि rजब भी शीर्ष बाएं वर्ण एक स्थान पर लागू होता है। यदि यह बजाय एक लोअरकेस चार है, तो इसे वापस कर दें। अन्यथा यह एक अपरकेस वर्ण होना चाहिए और #इसे पुनरावर्ती कहा जाता है, एक बार tailनीचे जाने के लिए और एक बार map tailसही जाने के लिए। यदि आवश्यक हो, तो !पुनरावर्ती कॉल से परिणामों में शामिल होता है ,। सभी इनपुट ग्रिड और पहचान समारोह के साथ शुरू होता है।


0

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

अभी भी यह नीचे गोल्फ के लिए तरीके की तलाश में है, लेकिन मुझे बस खुशी है कि मैं इसे एक-लाइनर में बदलने में कामयाब रहा।

lambda g,r=0,c=0:g[r][c]+'(%s)'%','.join([p(g,R,c)for R in range(r+1,len(g))if c<len(g[R])and' '!=g[R][c]][:1]+[p(g,r,C)for C in range(c+1,len(g[r]))if' '!=g[r][C]][:1])*g[r][c].isupper()
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.