Brain-Flak Classicインタープリターを作成してください!


18

Brain-Flak(Brainf ** kとFlak-Overstowのクロス)は、スタックベースの難解な言語です。この課題が投稿されて以来、言語は進化し更新されましたが、この言語のこの最初のリビジョンは「brain-flak classic」として知られています。

Brain-Flakクラシックコードの文字列を取得して評価するプログラムまたは関数を作成する必要があります。また、整数の(空の可能性のある)リストを取ります。Brain-Flakクラシックプログラムへの入力があります。

言語

Brain-Flakには、「左」と「右」として知られる2つのスタックがあります。アクティブなスタックは左から始まります。空のスタックがポップまたはピークされた場合、0が返されます。変数はありません。プログラムが開始されると、各入力がアクティブスタックに順番にプッシュされます(したがって、最後の入力がスタックの一番上になります)。

Brain-Flakプログラムで有効な文字はのみ()[]{}<>であり、常にバランスをとる必要があります。無効な文字がある場合、または角かっこが一致しない場合、未定義の動作が発生します。何でも有効です。

関数には、NiladsMonadsの 2つのタイプがあります。niladは 0の引数をとる関数です。すべてのniladsは次のとおりです。

  • () +1。
  • [] -1。
  • {} アクティブなスタックをポップします。
  • <> アクティブなスタックを切り替えます。

これらは評価されるときに連結されます。したがって、アクティブスタックの上部に「3」がある場合、このスニペットは次のとおりです。

()(){}

するために評価されます1 + 1 + active.pop()。5.に評価思われる<>0と評価されます。

モナドは1つの引数、Brain-Flakコードの塊を取ります。すべてのモナドは次のとおりです。

  • (n) アクティブなスタックで「n」を押します。
  • [n] 'n'をintおよび改行として出力します。
  • {foo}active.peek()!= 0の間に、fooを実行します。0¹に評価します。
  • <foo> fooを実行しますが、0として評価します。

これらの関数は、内部の値も返すため、

(()()())

3を押して

[()()()]

3を印刷しますが、

[(()()())]

印刷してプッシュします3。

プログラムの実行が完了すると、アクティブスタックに残っている各値が整数として出力され、間に改行が入ります。他のスタックの値は無視されます。

ルール:

  • プログラムは、(-128、127)の範囲の数字と、少なくとも255のスタックサイズをサポートする必要があります。より大きな、素晴らしいをサポートする場合。

  • アンダーフロー/オーバーフローは未定義です。

サンプルIO:

空のプログラム:

入力:なし

出力:なし

添加。ソース:

({}{})

入力:

2, 3

出力:

5

減算。ソース:

({}<>){({}[])<>({}[])<>}<>

入力:

2, 3

出力:

-1

乗算。ソース:

({}<>)<>({}[]){({}[])<>(({}))<>}<>{({}<>{})<>}<>

入力:

7, 8

出力:

56

フィボナッチ。ソース:

<>((()))<>{({}[])<>({}<>)<>(({})<>({}<>))<>}<>

入力:

5

出力:

13
8
5
3
2
1
1

真実の機械

{[({})]}

標準的な抜け穴が適用され、バイト単位の最短回答が優先されます。


  • ¹:これは実際には私の過ちでした。 {...} すべての実行の合計に評価する必要があります。これは、brain-flakの最もクールな機能の1つです。ただし、このチャレンジの目的のために、それ が0 評価されると仮定し{...} ます。

プログラムが処理する必要のある最小整数値に関する規則はありますか?
0

モナドは何を{...}評価しますか?
ニール

引き算の引数はどの順序ですか?私は私が期待するものの否定を得ています。
ニール

@Neilそれについてすみません。モナド{...}0に評価はまた、引数が順に押されるので2、押され、次に3押されるので、ときに、プログラムが開始されると、第2の入力は、( 3)スタックの最上部にあります。投稿でそれらの両方を明確にします。
DJMcMayhem

回答:


6

ピップ -n151 148 101 98バイト

YRVg;VqR^"{}()<>[]";,8R J,8<>2AL,8("POy|i o0Syl1v0W@y{ }1yPU$+[ ]&@y0 1P$+[ ]"R0" (V{"R1"i}) "^s)y

入力のリストをコマンドライン引数として取得し、Bdin-Flakコードを(1行の)stdinから取得します。オンラインでお試しください!

編集:翻訳と評価の戦略に切り替えることで、元のアプローチよりも多くのバイトを節約しました。

非ゴルフとコメント

このバージョンには、変換後のPipコードと、実行後のスタックの内容を示すデバッグ出力も含まれています。

;;; Setup ;;;

; y is the active stack, l is the off-stack
; y is initialized from command-line arguments
y:RVg   (reversed to put the last input at the top)
; l is preset to empty list by default

; p is the program (read from stdin)
p:q

; Translate from braces to numbers 0-7 (we do this so that the
; later replacement step won't try to replace the braces in the
; Pip code)
p R: ^"()[]{}<>" 0,8

;;; Replace nilads with the appropriate code ;;;

; () => o (variable preset to 1)
p R: 01 "o"

; [] => v (variable preset to -1)
p R: 23 "v"

; {} => POy|i
; Pop y; return that value OR i (variable preset to 0)
p R: 45 "POy|i"

; <> => (V{Syli})
; Eval the code Syl to swap stacks y and l, then return i (i.e. 0)
p R: 67 "(V{Syli})"

;;; Replace monads with the appropriate code ;;;

; ( ) => yPU$+[ ]&@y
; Sum ($+) the inside and push (PU) the sum onto y; return
; the just-pushed value, which is the first element of y (@y)
; y will always be truthy (nonempty), since we just pushed a value onto it
p R: 0 "yPU$+["
p R: 1 "]&@y"

; [ ] => P$+[ ]
; Sum ($+) the inside, print (P) the sum, and return it
p R: 2 "P$+["
p R: 3 "]"

; { } => (V{W@y{ }i})
; Eval the code W@y{ }, which wraps the inside in curly braces
; and runs it while (W) the first element of y (@y) is truthy
; (i.e. not zero, and not nil from an empty stack)
; Then return i (i.e. 0)
p R: 4 "(V{W@y{"
p R: 5 "}i})"

; < > => (V{ i})
; Eval the inside, then return i (i.e. 0)
p R: 6 "(V{"
p R: 7 "i})"

; Debug: print the resulting translated code and a blank line
Pp.n

;;; Run the code ;;;

; Eval the translated code
(Vp)

; Output the active stack, newline-separated
PyJn

; Debug: print the active stack and the off-stack
P"Active stack: ".RPy
"Off-stack: ".RPl

pipはこのチャレンジよりも新しいですか?
DJMcMayhem

@DJMcMayhem いいえ!また、チャレンジより新しい機能を使用していません。
DLosc

59

Brain-Flak Classic1271 1247 1239バイト

<>(()){<>((([][][][][])<(((({}){})(({})({}))[])({}(({})({}({})({}{}(<>)))))[])>{()<{}>}{})<{{}}{}>())}{}<>(<(({()(((<>))<>)}{}{<({}(([][][])((({})({}))[]{})){})>((){[]<({}{})((){[]<({}{}<>((({})({})){}{}){})(<>)>}{}){{}{}<>(<({}{}())>)(<>)}>}{}){(<{}{}{}((<>))<>>)}{}}<>)<{({}[]<({}<>)<>{(<{}>)<>{<>({}[])}{}<>({}<>)(<>)}{}>)}{}<>>)>)<>{(({}[])(){(<{}>)<><(({})[])>[][][][]{()()()()(<{}>)}{}<>}{}<>)<>}<>{}{(({})<({()<<>({}<>)>}{})>([]))((){[](<(({}()()(<>))()()()){(<{}>)<>}>)}{}<>){{}((){[]<({}())((){[]<({}())((){[]<({}())((){[]<({}())((){[]<({}())((){[]<({}())((){[](<{}<>{({}<>)<>}{}(({}))({<{}({}<>)<>>{}(<<>({}[]<>)>)}<><{({}<>)<>}>{})>)}{}){{}{}(<([])>)}>}{}){{}<>{({}<>)<>}{}((({})())<{({}[]<({}<>)<>>)}>{}){({}[]<><({}<><({()<({}[]<({}<>)<>>)>}{}<>)><>)<>({()<({}[]<({}<>)<>>)>}{}<>)>)}<>(<{({}<>)<>}>)}>}{}){{}{}(<(())>)}>}{}){(<{}{}>)<>{({}<>)<>}{}(({}))({<{}({}<>)<>>({})(<<>({}<>)>)}<><{({}<>)<>}>){{}([][][])<>(((<{}>)<>))}}>}{}){{}(<([{}])>)}>}{}){{}((<{}>))}>}{}){{}(({})(<()>)<<>{({}<>)<>}{}({}()<>)<>>)<>(<({}<>)>)<>{({}<>)<>}}{}(<({}<({}<>)<>>{})<>({}<>)>)<>(<({}())>)}{}({}<{({}[]<({}<>)<>>)}{}>){((({}[]<>){(<{}({}<>)>)}{}())<{({}()<({}<>)<>(({})[])>{[][](<{}>)}{})}{}>()){{}(<>)}}{}}{}{({}[]<[{}]>)}{}{({}[]<{}>)}{}

オンラインでお試しください!

{...}モナドの状態に関するバグの修正から+4バイト、さまざまなゴルフから-36バイト。

1238バイトのコード、-aフラグ用の+1バイト(言語フラグと組み合わせることができます)。

これは{...}、チャレンジ仕様ごとにゼロとして評価されるようになりました。Brain-Flak自体は{...}、このチャレンジが投稿される2日前の2016年5月7日のバグ修正以降のすべての実行の合計として評価されていることに注意してください。

次のコード{...}は、すべての実行の合計としてBrain-Flak Classicを正しく解釈します。2人の通訳者の唯一の違いは、1 {}ニラッドの配置です。

<>(()){<>((([][][][][])<(((({}){})(({})({}))[])({}(({})({}({})({}{}(<>)))))[])>{()<{}>}{})<{{}}{}>())}{}<>(<(({()(((<>))<>)}{}{<({}(([][][])((({})({}))[]{})){})>((){[]<({}{})((){[]<({}{}<>((({})({})){}{}){})(<>)>}{}){{}{}<>(<({}{}())>)(<>)}>}{}){(<{}{}{}((<>))<>>)}{}}<>)<{({}[]<({}<>)<>{(<{}>)<>{<>({}[])}{}<>({}<>)(<>)}{}>)}{}<>>)>)<>{(({}[])(){(<{}>)<><(({})[])>[][][][]{()()()()(<{}>)}{}<>}{}<>)<>}<>{}{(({})<({()<<>({}<>)>}{})>([]))((){[](<(({}()()(<>))()()()){(<{}>)<>}>)}{}<>){{}((){[]<({}())((){[]<({}())((){[]<({}())((){[]<({}())((){[]<({}())((){[]<({}())((){[](<{}<>{({}<>)<>}{}(({}))({<{}({}<>)<>>{}(<<>({}[]<>)>)}<><{({}<>)<>}>{})>)}{}){{}{}(<([])>)}>}{}){{}<>{({}<>)<>}{}((({})())<{({}[]<({}<>)<>>)}>{}){({}[]<><({}<><({()<({}[]<({}<>)<>>)>}{}<>)><>)<>({()<({}[]<({}<>)<>>)>}{}<>)>)}<>(<{({}<>)<>}>)}>}{}){{}{}(<(())>)}>}{}){(<{}>)<>{({}<>)<>}{}(({}))({<{}({}<>)<>>({})(<<>({}<>)>)}<><{({}<>)<>}>{}){{}([][][])<>(((<{}>)<>))}}>}{}){{}(<([{}])>)}>}{}){{}((<{}>))}>}{}){{}(({})(<()>)<<>{({}<>)<>}{}({}()<>)<>>)<>(<({}<>)>)<>{({}<>)<>}}{}(<({}<({}<>)<>>{})<>({}<>)>)<>(<({}())>)}{}({}<{({}[]<({}<>)<>>)}{}>){((({}[]<>){(<{}({}<>)>)}{}())<{({}()<({}<>)<>(({})[])>{[][](<{}>)}{})}{}>()){{}(<>)}}{}}{}{({}[]<[{}]>)}{}{({}[]<{}>)}{}

オンラインでお試しください!

(どちらかのインタープリターへの)入力は、解釈するBrain-Flak Classicプログラムで、次に改行、スペースで区切られた整数のリストです。入力に対して検証は実行されません。プログラムまたは入力が空白であっても、改行が必要です。

最初のステップは、括弧で始まるすべての入力を解析することです。

# Move to right stack, and push 1 to allow loop to start
<>(())
{
   # While keeping -5 on third stack:
   <>((([][][][][])<

       # Pop bracket or newline k from left stack, and push 0, k-10, k-40, k-60, k-91, k-123 on right stack
       (((({}){})(({})({}))[])({}(({})({}({})({}{}(<>)))))[])

   # Search this list for a zero, and push the number of nonzero entries popped minus 5 
   # (thus replacing the 0 if it was destroyed)
   >{()<{}>}{})

   # Remove rest of list, and push the same number plus 1
   # Result is -4 for {, -3 for [, -2 for <, -1 for (, 0 for newline, or 1 for everything else (assumed closing bracket)
   <{{}}{}>())

# Repeat until newline found
}{}<>

次に、整数が解析されます。通常、これは必要ありませんが、入力はASCIIとして取得されました。ただし、これには銀色の裏地があります。テキスト入力によりスタックの高さを決定できるため、スタックの高さniladにアクセスできない場合に物事が簡単になります。

整数は、2番目のスタックで2つの数値に解析されます。1つは絶対値用で、もう1つは符号用です。その後、これらは最初のスタックに戻されます。

解釈されたスタックは、最初のスタックのコードの下に、現在のスタックの高さ、現在のスタック、他のスタックの高さ、他のスタックの順に格納されます。他のスタックの高さの0は、最初に読み取られたときに暗黙のゼロになるため、この時点でプッシュする必要はありません。

(<((

    # If stack nonempty, register first stack entry.
    {()(((<>))<>)}{}

    # For each byte k of input:
    {

        # Push -3, -13, and k-32
        <({}(([][][])((({})({}))[]{})){})>

        # Evaluate to 1 if space
        # If not space (32):
        ((){[]<

            # If not minus (45):
            ({}{})((){[]<

                # Replace top of right stack (n) with 10*n + (k-48)
                ({}{}<>((({})({})){}{}){})(<>)

            # Else (i.e., if minus):
            >}{}){

                # Remove excess "else" entry and -3
                {}{}

                # Set sign to negative (and destroy magnitude that shouldn't even be there yet)
                <>(<({}{}())>)(<>)}

        # Else (i.e., if space):
        >}{}){

            # Remove working data for byte, and push two more 0s onto right stack
            (<{}{}{}((<>))<>>)

    # Push number of integers found
    }{}}<>)

    # For each integer:
    <{({}[]<

        # Move magnitude back to left stack
        ({}<>)<>

        # If sign is negative, negate
        {(<{}>)<>{<>({}[])}{}<>({}<>)(<>)}{}

    >)}{}

    # Push stack height onto stack
    <>>)

# Push 0
>)

これで、コードの表現は左スタックに戻ります。後で作業を簡単にするために、niladsの開始かっこから4を引いて、各操作が-1〜-8の一意の整数になるようにします。

# For each bracket in the code:
<>{

    # Push k-1 and evaluate to k
    (({}[])()

    # If not closing bracket:
    {

        # Check next bracket (previously checked, since we started at the end here)
        (<{}>)<><(({})[])>

        # Subtract 4 if next bracket is closing bracket
        # Inverting this condition would save 8 bytes here, but cost 12 bytes later.
        [][][][]{()()()()(<{}>)}{}

    <>}{}

    # Push result onto left stack
    <>)

<>}<>{}

プログラムの主要部分は、実際に指示を解釈することです。メインループの各反復の開始時、現在の命令は左スタックの最上部にあり、それ以降はすべて同じスタック上にあり、それ以前のすべては右スタックにあります。私はこれを特定のページに開かれた本を持つように視覚化する傾向があります。

{

    (

        # Get current instruction
        ({})

        # Move all code to left stack, and track the current position in code
        <({()<<>({}<>)>}{})>

        # Push -1, signifying that the code will move forward to just before a matching }.
        # In most cases, this will become 0 (do nothing special) before it is acted upon
        ([])

    # Push instruction minus 1
    )

    # If opening bracket:
    ((){[](<

        # Push instruction+1 and instruction+4
        (({}()()(<>))()()())

        # If instruction+4 is nonzero (not loop monad), replace the earlier -1 with 0 to cancel forward seek
        # This would be clearer as {(<{}>)<>(<{}>)<>}, but that would be unnecessarily verbose
        {(<{}>)<>}

    # Else (i.e., if closing bracket):
    >)}{}<>){

# If closing bracket, parse command
# Post-condition for all: if not moving to {, pop two and push evaluation, 0.
# (For nilads, can assume second from top is 0.)
# If moving to {, pop one, push -3, 0, 0.

        # Seven nested if/else statements, corresponding to eight possible instruction.
        # The "else" statements end with 0 already on the stack, so no need to push a 0 except in the innermost if.
        # Each one beyond the first increments the instruction by 1 to compare the result with 0
        # Each instruction will pop the instruction, leaving only its evaluation (with a 0 on top).
        {}((){[]<
        ({}())((){[]<
        ({}())((){[]<
        ({}())((){[]<
        ({}())((){[]<
        ({}())((){[]<
        ({}())((){[](<

            # -7: pop
            # Pop instruction to reveal existing 0 evaluation
            {}

            # Move code out of the way to access stack
            <>{({}<>)<>}{}

            # Duplicate stack height (only useful if stack height is zero)
            (({}))

            (

                # If stack height nonzero
                {

                    # Save stack height on second stack
                    <{}({}<>)<>>

                    # Pop stack
                    {}

                    # Move stack height back and subtract 1
                    (<<>({}[]<>)>)

                }

                # Move code back to normal position
                <><{({}<>)<>}>{}

            # Evaluate as popped entry (0 if nothing popped)
            )

        # (else)
        >)}{}){

            # -6: -1 nilad
            # Just evaluate as -1
            {}{}(<([])>)

        # (else)
        }>}{}){

            # -5: swap nilad
            # Move code out of the way to access stack
            {}<>{({}<>)<>}{}

            # Number of integers to move: stack height + 1 (namely, the stack height and every entry in the stack)
            ((({})())

            # Move to second stack
            <{({}[]<({}<>)<>>)}>{}

            # Do (stack height + 1) times again
            ){({}[]<><

                # Get stack element
                ({}<><

                    # Move alternate (interpreted) stack to second (real) stack, and push length on top of it
                    ({()<({}[]<({}<>)<>>)>}{}<>)

                # Push current stack element below alternate stack
                ><>)

                # Move alternate stack back above newly pushed element
                <>({()<({}[]<({}<>)<>>)>}{}<>)

            >)}

            # Move code back to normal position
            <>(<{({}<>)<>}>)

        # (else)
        }>}{}){

            # -4: 1
            # Just evaluate to 1
            {}{}(<(())>)

        # (else)
        }>}{}){

            # -3: loop
            # Create zero on stack while keeping existing evaluation
            # This becomes (<{}{}>) in the version that meets the challenge spec
            (<{}>)

            # Move code out of the way to access stack
            <>{({}<>)<>}{}

            # Duplicate stack height
            (({}))

            (

                # If stack height nonzero
                {

                    # Save stack height on second stack
                    <{}({}<>)<>>

                    # Peek at top of stack
                    ({})

                    # Move stack height back
                    (<<>({}<>)>)

                }

                # Move code back to normal position
                <><{({}<>)<>}>

            # Look at peeked entry
            # Remove the {} in the version meeting the challenge spec
            {})

            # If peeked entry is nonzero
            {

                # Replace -3 instruction on third stack
                {}([][][])

                # Replace loop indicator to 0 (to be incremented later to 1)
                <>(((<{}>)

                # Create dummy third stack entry to pop
                <>))

            }

        # (else)
        }>}{}){

            # -2: print
            # Just print evaluation without modifying it
            {}(<([{}])>)

        # (else)
        }>}{}){

            # -1: evaluate as zero
            # Just change evaluation to 0
            {}((<{}>))

        # else
        }>}{}){

            # 0: push
            # Get current evaluation (without modifying it)
            {}(({})

                # Create zero on stack as barrier
                (<()>)

                # Move code out of the way to access stack
                <<>{({}<>)<>}{}

                # Increment stack height and save on other stack
                ({}()<>)<>

            # Push evaluation
            >)

            # Move stack height back (and push zero)
            <>(<({}<>)>)

            # Move code back to normal position
            <>{({}<>)<>}

        }{}

        # Update third stack by adding evaluation to previous entry's evaluation
        # Previous entry's instruction is saved temporarily on left stack
        (<({}<({}<>)<>>{})<>({}<>)>)

        # Increment loop indicator
        # If instruction was loop monad and top of stack was nonzero, this increments 0 to 1 (search backward)
        # Otherwise, this increments -1 to 0 (do nothing)
        <>(<({}())>)

    }{}

    # While holding onto loop indicator
    ({}<

        # Go to immediately after executed symbol
        {({}[]<({}<>)<>>)}{}

    >)

    # If looping behavior:
    {

        # Switch stack and check if searching forward
        ((({}[]<>)

        # If so:
        {

            # Move just-executed { back to left stack, and move with it
            (<{}({}<>)>)

        }{}

        # Either way, we are currently looking at the just-executed bracket.
        # In addition, the position we wish to move to is on the current stack.

        # Push unmodified loop indicator as initial value in search
        ())

        # While value is nonzero:
        <{

            # Add 1
            ({}()

                # Move current instruction to other stack
                <({}<>)<>

                # Check whether next instruction is closing bracket
                (({})[])>

                # If opening bracket, subtract 2 from value
                {[][](<{}>)}{}

            )

        }{}>

        # If searching backward, move back to left stack
        ()){{}(<>)}

    }{}

}

メインループを終了すると、すべてのコードが正しいスタックに配置されます。左側のスタック上の唯一のものは、ゼロと2つの解釈されたスタックです。正しい出力を生成するのは簡単です。

# Pop the zero
{}

# Output current stack
{({}[]<[{}]>)}{}

# Discard other stack to avoid implicit printing
{({}[]<{}>)}{}

12
:O何...わかりました、すぐに賞金を稼ぎます。良くやった!:D
DJMcMayhem

4
これをまっすぐにさせてください...あなたは、解釈されるべき言語のインタプリタを作成しました。YoDawg
tisaconundrum

OK、なぜ2桁の投票数しか持っていないのですか?
-NieDzejkob

でアキュムレータを正しく実装するのは良い仕事です{...}。これは、現代のブレインフラックおよびブレインフラッククラシックの正しい動作です。ただし{...}、0 と評価されるチャレンジで記述しました。その機能を削除することにより、元の
ファイル

@DJMcMayhem修正済み。Brain-Flakの仮想バージョンにインタープリター全体を移植させないでください。
ニトロドン

8

APL、255 257バイト

b←{S←(⌽⍺)⍬
e←{0=⍴⍵:0
v+∇⊃_ v←∇{r←⊂2↓⍵
'()'≡n←2↑⍵:r,1
'[]'≡n:r,¯1
'{}'≡n:r,{i←⊃⊃⊃S⋄S[1]↓⍨←1⋄i}⍬
'<>'≡n:r,0⊣S⌽⍨←1
r←⊂⍵↓⍨i←0⍳⍨(+\c=⍵)-+\')]>}'['([<{'⍳c←⊃⍵]=⍵
i←1↓¯1↓c←i↑⍵
'('=c←⊃c:r,S[1],⍨←⍺⍺i
'['=c:r,+⎕←⍺⍺i
'{'=c:r,{0≠⊃⊃⊃S:∇e i⋄0}⍬
'<'=c:r,0⊣⍺⍺i}⍵}
⎕←⍪⊃S⊣e⍵}

これは、プログラムを右引数として、プログラム入力を左引数として受け取ります。

      2 3 b '({}{})'
5
      2 3 b '({}<>){({}[])<>({}[])<>}<>'
¯1
      7 8 b '({}<>)<>({}[]){({}[])<>(({}))<>}<>{({}<>{})<>}<>'
56
      5 b '<>((()))<>{({}[])<>({}<>)<>(({})<>({}<>))<>}<>'
13
 8
 5
 3
 2
 1
 1

未ゴルフバージョン:こちら



6

Python 3、429バイト

import re
S='s+=[v];v=0';T='v+=s.pop()';i=0
d={'()':'v+=1','(':S,')':'a+=[v];'+T,'[]':'v-=1','[':S,']':'print(v);'+T,'<>':'a.reverse()','<':S,'>':T,'{}':'v+=0if a[-1]==""else a.pop()','{':S+';while a[-1]:','}':T}
def r(m):global i;t=m.group();i-=(t=='}');s=' '*i;i+=(t=='{');return''.join(s+r+'\n'for r in d[t].split(';'))
def g(c,*a):
 a,s,v=['']+list(a),[],0;exec(re.sub(r'[<({[]?[]})>]?',r,c));
 while a[-1]!="":print(a.pop())

のように使用 g('[{}{}]', 2, 3)

これは、使用してre.sub「コンパイル」のpythonに脳高射砲源に、その後のpythonを実行します。(デバッグ用に置き換えexecprint、Pythonコードのリストを取得します)

ネストされたwhileループを適切にインデントすると、コード内の多くのバイトが消費されます。


3

Python、616バイト

手順:

  1. Pythonで実行
  2. リストを[1,2,...]形式で入力し、Enterキーを押します
  3. プログラムを貼り付けてから、もう一度Enterキーを押します
  4. 完了

基本的に、このプログラムは、Brain-flakコードを再帰的に「コンパイル」してネストされたリストにし、そのリストを再帰的に解釈します。おそらく2つを組み合わせる方法があります...

後でロジックを再試行してみます。

y="([{<)]}>"
w,z,g=print,len,input
def c(s):
 if z(s)<1:return[]
 t,i,o=[],1,0
 t.append(y.index(s[0]))
 while z(t)>0:
  x=y.index(s[i])
  if x<4:t.append(x)
  else:o=t.pop()
  i+=1
 r=[[o,c(s[1:i-1])]]
 r.extend(c(s[i:]))
 return r
p=lambda t:t.pop()if z(t)>0 else 0
k=lambda t:t[z(t)-1]if z(t)>0 else 0
r,l=[],eval(g())
a=l
def i(u):
 v=0
 global a
 for t,n in u:
  if t<1:
   if n:o=i(n);v+=o;a.append(o)
   else:v+=1
  if t==1:
   if n:o=i(n);v+=o;w(o)
   else:v-=1
  if t==2:
   if n:
    while k(a)!=0:i(n)
   else:v+=p(a)
  if t>2:
   if n:i(n)
   elif a==l:a=r
   else:a=l
 return v
i(c(g()))
for n in a:w(n)

3

Perl 5.6、419 414バイト

少しゴルフをしましたが、おそらく改善の余地があります。読みやすくするために、ここに改行とタブを追加しました。

use Text::Balanced extract_bracketed;
$s=shift;
@a=reverse@ARGV;
sub p
{
    my($c)=@_;
    my$s=0;
    while(my$n=extract_bracketed($c)){
        $s+='()'eq$n||'{}'eq$n&&shift@a;
        $s-='[]'eq$n;
        @t=@a,@a=@i,@i=@t if'<>'eq$n;
        my$m=chop($n);
        $n=substr($n,1);
        if($n){
            p($n)while'}'eq$m&&$a[0];
            p($n)if'}'ne$m;
            $s+=$v,unshift@a,$v if')'eq$m;
            $s+=$v,print"n=$n m=$m v=$v\n"if']'eq$m;
        }
    }
    $v=$s;
}
p($s);
foreach(@a){
    print"$_\n";
}

1

Pythonの2361、348のバイト

c,s=input();s=s,[]
a=s[0]
def w():global a,s;s=s[::-1];a=s[0];return 0
def p(c):a.append(c);return c
def n(c):print c;return c
z=lambda c:0
def l(f):
 global a
 while a and a[-1]:f()
 return 0
for x,y in zip("() ( [] {} <> [ < { } ] >".split(),"+1 +p( -1 +(len(a)and(a.pop())) +w() +n( +z( +l(lambda: ) ) )".split()):c=c.replace(x,y)
exec c
print a

オンラインでお試しください!

@Mrのおかげで-13バイトが節約されました。Xcoder!

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