2次元構文を解析する


25

バックグラウンド

アリスとボブは、すべてのPPCGチャレンジに勝つためにゴルフ言語を作成しています。アリスは> <>のような2次元言語を作成したいと考えていますが、ボブはJのようなプレフィックスとインフィックスの構文を好みます。妥協として、2次元のプレフィックスとインフィックスの言語を作成することにしました。パーサーは書くのが面倒で、あなたの助けが必要です!

構文仕様

アリスとボブの言語には、小文字のASCII文字で表される変数と、大文字のASCII文字で表される関数があります。関数は、1つまたは2つの引数で呼び出すことができます。プログラムは、文字の矩形グリッドで、スペース、および左上隅には、スペースを含めることはできません。これは有効なプログラムの例です:a-zA-Za-zA-Z

F Gy
H   
R x 

プログラムが解析されると、1文字の変数と形式<func>(<arg>)またはの関数呼び出しを含むCスタイル言語(C、Java、Python ...)の式に変換されます<func>(<arg1>,<arg2>)。たとえば、上記のプログラムは次の式になります。

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

解析プロセスの詳細は次のとおりです。

  • スペースは単なるフィラーであるため、解析されません。
  • すべての変数a-zは常にそれ自体として解析されます。
  • すべての関数A-Zは、関数呼び出しとして解析されます。その引数は、グリッドの下でこの順序で右にある最も近い式です。これらのいずれかのみが存在する場合は、それが唯一の引数として与えられます。すべての関数には、グリッドに少なくとも1つの引数があると仮定できます。

上記の例では、変数xyはそれ自体として解析されます。この関数Rx、その下とその右に何もないので、1引数呼び出しとして解析されますR(x)。同様に、の下にあるため、Hとして解析されます。関数はその下と右にあるため、として解析され、同様にのために解析されます。左上隅で解析される式は、解析プロセスの結果です。H(R(x))RGxyG(x,y)F

入出力

入力は、空でない長方形の文字配列です。これは常にアリスとボブの言語で有効なプログラムになりますが、出力には使用されない表現が含まれる場合があります。出力は、上記のプロセスの結果として解析された式になります。

ルールとスコアリング

関数の完全なプログラムを書くことができます。最小のバイトカウントが優先され、標準の抜け穴は許可されません。

テストケース

これらは、形式の間に与えられ、ケース間にgrid <newline> expressionハイフン---があります。SE形式では一部の行が空白のままになりますが、空白で埋める必要があります。

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)))は適切か、フォーマットは固定されていますか?
コアダンプ

1
@coredumpこのチャレンジでは、出力形式は厳密です。アリスとボブは、解析された式を直接使用できるようにしたいと考えています。
ズガーブ

言語の「中置」部分はどこにありますか?プレフィックスのみが表示されます。
パウロEbermann

6
この構文で実際に言語を作成してください。:)
マーティンエンダー

4
フォローアップの課題:この構文のメタゴルファーを記述します(式ツリーが与えられ、それに対応する最小のグリッドを見つけます)。さらに困難な場合は、可換関数と非可換関数を区別してください。
マーティンエンダー

回答:


8

CJam、67 62 60 58 57 54バイト

4バイトを節約してくれたDennisに感謝します。

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

これは名前付きブロック(関数)Jを定義し、スタックに残します。関数自体は、入力グリッドを表すスタック上の文字列の配列を予期し、代わりに目的の文字列を残します。

ここでテストしてください。

投稿されてからこの問題に取り組むつもりでしたが、どうやら十分な動機付けをするために、賞金と過度に長いPythソリューションが必要だったようです。

説明

ソリューションはもちろん再帰的であり、徐々に文字列を構築します。

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

(4つのスペースは実際にはタブです)

rの最初の引数として文字の2dリストを取ります。


5

Pyth、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時間?)。Pythは本当にこのために設計されていません...

ここで試してみてください

説明と同等のpythonの試み

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)

関数Pprintassignそれらが与えられたものを返す場所。


多くの簡潔さ。そのようなすごい。
アディソンクランプ

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、左上の文字がスペースの場合に適用されます。代わりに小文字の文字である場合は、それを返します。それ以外の場合は、大文字でなければならず#、1回はtail下に、もう1回はmap tail右に、再帰的に呼び出されます。必要に応じ!,、再帰呼び出しの結果をで結合します。すべては、入力グリッドと恒等関数から始まります。


0

Python 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()
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.