İki boyutlu bir sözdizimini ayrıştırma


25

Arka fon

Alice ve Bob, her PPCG yarışmasını kazanmak için bir golf dili yaratıyor. Alice,> <> gibi iki boyutlu bir dil yapmak istiyor, ancak Bob, J'deki gibi bir önek eki sözdizimini tercih ediyor. Ayrıştırıcı yazmak bir acıdır ve sizin yardımınıza ihtiyaçları var!

Sözdizimi özellikleri

Alice ve Bob'un dilinde, küçük ASCII harfleriyle temsil edilen değişkenlera-z ve büyük ASCII harfleriyle temsil edilen işlevler vardır A-Z. Bir fonksiyon bir veya iki argümanla çağrılabilir. Bir program , harflerin a-zA-Zve boşlukların dikdörtgen bir ızgarasıdır ve sol üst köşede boşluk bulunmamalıdır. Bu geçerli bir program örneği:

F Gy
H   
R x 

Program ayrıştırıldığında, tek harfli değişkenler ve işlev çağrıları <func>(<arg>)ya da biçimindeki bir C tarzı dilin (C, Java, Python ...) ifadesine dönüştürülür <func>(<arg1>,<arg2>). Örneğin, yukarıdaki program bu ifadeyle sonuçlanır:

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

Ayrıştırma işleminin detayları aşağıdaki gibidir:

  • Boşluklar yalnızca doldurucudur, bu nedenle ayrıştırılmazlar.
  • Her değişken a-zher zaman kendisi gibi ayrıştırılır.
  • Her işlev A-Zbir işlev çağrısı olarak ayrıştırılır. Argümanları, bu düzende altındaki ve kılavuzdaki en yakın ifadelerdir. Bunlardan sadece biri mevcutsa, tek argüman olarak verilir. Tüm fonksiyonların ızgarada en az bir argüman olduğunu varsayabilirsiniz.

Yukarıdaki örnekte değişkenler xve ykendileri ayrıştırılır. İşlevin Raltında ve xsağında hiçbir şey yoktur , bu nedenle tek argüman çağrısı olarak ayrıştırılır R(x). Benzer şekilde, altında olduğundan beri Hayrıştırılır . İşlev , altında ve sağında bulunur, bu nedenle olarak ve benzer şekilde ayrıştırılır . Sol üst köşede ayrıştırılan ifade, ayrıştırma işleminin sonucudur.H(R(x))RGxyG(x,y)F

Giriş ve çıkış

Girişiniz boş olmayan dikdörtgen bir karakter dizisidir. Her zaman Alice ve Bob'un dilinde geçerli bir program olacak, ancak çıktıda kullanılmayan ifadeler içerebilir. Çıktınız yukarıdaki işlemden kaynaklanan ayrıştırılmış ifade olacaktır.

Kurallar ve puanlama

Bir fonksiyonun tam bir programını yazabilirsiniz. En düşük bayt sayısı kazanır ve standart boşluklar izin verilmez.

Test durumları

Bunlar , vakalar arasında grid <newline> expressionkısa çizgi bulunan biçimde verilir ---. SE formatı bazı satırları boş bırakır, ancak boşluklarla doldurulmaları gerekir.

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)))

Gibi bir çıktı (A (B (D x)) (C (D x)))uygun olur mu veya format sabit mi?
coredump,

1
@ coredump Bu mücadelede, çıktı formatı katıdır; Alice ve Bob ayrıştırılmış ifadeyi doğrudan kullanabilmek istiyor.
Zgarb

Dilin "ek" kısmı nerede? Sadece ön ek görüyorum.
Paŭlo Ebermann,

6
Lütfen bu sözdizimiyle bir dil oluşturabilir misiniz? :)
Martin Ender

4
Takip zorluğu: Bu sözdizimi için bir meta-golfçü yazın (bir ifade ağacı verildiğinde, ona karşılık gelen en küçük ızgarayı bulun). Ekstra zorluk için, değişmeli ve değişmeli olmayan işlevler arasında ayrım yapın.
Martin Ender

Yanıtlar:


8

CJam, 67 62 60 58 57 54 bayt

4 byte tasarruf için Dennis teşekkür ederiz.

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

Bu, adlandırılmış bir bloğu (işlevi) tanımlar Jve yığında bırakır. İşlevin kendisi yığın üzerinde girdi ızgarasını temsil eden bir dizi dizge bekler ve istenen dizgiyi yerine bırakır.

Burada test et.

Yayınlandığından beri bununla başa çıkmak istedim, ama görünüşe göre kendimi yeterince motive etmek için bir lütuf ve çok uzun bir Pyth çözümüne ihtiyacım vardı.

açıklama

Çözüm elbette özyinelemelidir ve kademeli olarak ipi oluşturur.

{
  :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

Python 2, 227 223 192 182 179 177 bayt

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()

(Dört boşluk aslında sekmedir)

R'nin ilk argümanı olarak 2d karakter listesini alır.


5

Pyth, 97 bayt

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

Tanrım, uzun zaman aldı (yaklaşık 5/6 saat?). Pyth gerçekten bunun için tasarlanmadı ...

Burada dene .

Python eşdeğeri olduğu gibi açıklamada da teşebbüs

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)

Fonksiyonların nerede olduğunu Pprintve assignne verildiğini geri verir.


Çok karar. Böyle bir vay.
Addison Crump,

5

Haskell, 124 122 120 119 bayt

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)

Kullanım örneği: (#id) ["RT Hq ","I xR k"]-> "R(I(x),T(H(R(k),q)))".

Nasıl çalışır: giriş kılavuzunun yanı sıra, rişlev #, sol üst karakter boşluk olduğunda g, uygulanan bağımsız değişken olarak başka bir işlev alır r. Bunun yerine küçük harf karakterse, döndürün. Aksi halde büyük harf olmalı ve #tekrar tekrar, bir kez tailaşağı gitmek için bir kez ve map tailsağa gitmek için çağrılır . !özyinelemeli aramaların sonuçlarını ,gerekirse bir ile birleştirir . Her şey giriş ızgarası ve kimlik işlevi ile başlar.


0

Python 3, 187 bayt

Hala bu golf oynamak için yollar arıyor, ama ben sadece bir astar haline çevirmeyi başardığı için memnunum.

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()
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.