두뇌 고전적인 통역사를 작성하십시오!


18

Brain-Flak (Brainf ** k와 Flak-Overstow의 교차점)은 스택 기반의 난해한 언어입니다. 이 과제가 게시 된 이후로 언어는 발전하고 업데이트되었지만 언어의 첫 번째 개정판은 "brain-flak classic"으로 알려져 있습니다.

Brain-Flak 클래식 코드 문자열을 가져 와서 평가하는 프로그램이나 함수를 작성해야합니다. 또한 (가능한 빈) 정수 목록이 필요합니다. Brain-Flak 클래식 프로그램에는 입력이 있습니다.

언어

Brain-Flak에는 '왼쪽'과 '오른쪽'으로 알려진 두 개의 스택이 있습니다. 활성 스택은 왼쪽에서 시작합니다. 빈 스택이 튀어 나오거나 들여다지면 0을 반환합니다. 변수가 없습니다. 프로그램이 시작되면 각 입력은 순서대로 활성 스택으로 푸시됩니다 (마지막 입력은 스택 맨 위에 있음).

Brain-Flak 프로그램에서 유일하게 유효한 문자는 ()[]{}<>이며 항상 균형을 유지 해야합니다 . 유효하지 않은 문자가 있거나 대괄호가 일치하지 않으면 정의되지 않은 동작이 발생합니다. 모든 것이 유효합니다.

함수에는 NiladsMonads 의 두 가지 유형이 있습니다 . nilad은 0 인수를 취하는 함수이다. 모든 nilads는 다음과 같습니다.

  • () +1.
  • [] -1.
  • {} 활성 스택을 팝하십시오.
  • <> 활성 스택을 토글합니다.

이들은 평가 될 때 함께 연결됩니다. 따라서 활성 스택 위에 '3'이 있으면이 스 니펫은 다음과 같습니다.

()(){}

로 평가 될 것이다 1 + 1 + active.pop()5로 평가하는 것이다 <>0으로 평가합니다.

모나드는 브레인-플락 (Brain-Flak) 코드 덩어리라는 하나의 주장을 취합니다. 다음은 모든 모나드입니다.

  • (n) 활성 스택에서 'n'을 누릅니다.
  • [n] 'n'을 int 및 줄 바꿈으로 인쇄하십시오.
  • {foo}active.peek ()! = 0 인 동안 foo를 수행하십시오. 0¹로 평가됩니다.
  • <foo> foo를 실행하지만 0으로 평가하십시오.

이 함수는 내부의 값도 반환하므로

(()()())

3을 밀고

[()()()]

3을 인쇄하지만

[(()()())]

인쇄 하고 3을 누릅니다.

프로그램 실행이 완료되면 활성 스택에 남은 각 값이 줄 바꿈 사이에 정수로 인쇄됩니다. 다른 스택의 값은 무시됩니다.

규칙 :

  • 프로그램은 (-128, 127) 범위의 숫자와 255 이상의 스택 크기를 지원해야합니다.

  • 언더 플로우 / 오버 플로우가 정의되지 않았습니다.

샘플 IO :

빈 프로그램 :

입력 : 없음

출력 : None

부가. 출처:

({}{})

입력:

2, 3

산출:

5

빼기. 출처:

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

입력:

2, 3

산출:

-1

곱셈. 출처:

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

입력:

7, 8

산출:

56

피보나치. 출처:

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

입력:

5

산출:

13
8
5
3
2
1
1

진실 기계

{[({})]}

표준 허점이 적용되며 바이트 단위의 최단 답변이 이깁니다.


  • ¹ : 이것은 실제로 제 실수입니다. {...} 모든 실행의 합으로 평가해야합니다. IMO는 뇌-플래 크의 가장 멋진 기능 중 하나입니다. 그러나이 문제를 해결하기 위해 0으로 평가 한다고 가정합니다 {...} .

프로그램이 처리해야하는 최소 정수 값에 관한 규칙이 있습니까?
0 '

모나드 {...}는 무엇을 평가합니까?
Neil

빼기 인수는 어떤 순서로되어 있습니까? 나는 내가 기대하는 것을 부정하고 있습니다.

@Neil 죄송합니다. 모나드 {...}는 0으로 평가됩니다. 또한 인수는 순서대로 푸시되므로 2푸시 된 다음 3푸시되므로 프로그램이 시작될 때 두 번째 입력 ( 3)이 스택의 맨 위에 있습니다. 나는 게시물의 두 가지를 분명히 할 것입니다.
DJMcMayhem

답변:


6

-n , 151 (148) 101 98 바이트

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

입력 목록을 명령 행 인수로 사용하고 Brain-Flak 코드를 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

핍이이 도전보다 새로운가요?
DJMcMayhem

@DJMcMayhem 아니 ! 또한 도전보다 새로운 기능을 사용하고 있지 않습니다.
DLosc

59

Brain-Flak Classic , 1271 1247 1239 바이트

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

온라인으로 사용해보십시오!

{...}모나드 의 조건으로 버그를 수정하여 +4 바이트 , 다양한 골프에서 -36 바이트.

1238 바이트의 코드, -a플래그의 경우 +1 바이트 (언어 플래그와 결합 가능).

이제 {...}챌린지 사양 당 0으로 평가 됩니다. Brain-Flak 자체는 {...}이 챌린지가 게시되기 2 일 전 2016 년 5 월 7 일 버그 수정 이후 모든 실행의 합으로 평가 되었습니다.

다음 코드는 Brain-Flak Classic {...}을 모든 런의 합으로 올바르게 해석 합니다. 두 통역사 간의 유일한 차이점은 하나의 {}nilad 배치입니다 .

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

온라인으로 사용해보십시오!

인터프리터 (interpreter)의 입력은 해석을위한 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에 액세스 할 수없는 경우 작업을 단순화합니다.

정수는 두 번째 스택에서 두 개의 숫자로 구문 분석됩니다. 하나는 절대 값이고 다른 하나는 부호입니다. 그런 다음 첫 번째 스택으로 다시 이동됩니다.

해석 된 스택은 현재 스택 높이, 현재 스택, 기타 스택 높이, 기타 스택 순서로 첫 번째 스택의 코드 아래에 저장됩니다. 다른 스택 높이의 0은 처음 읽을 때 암시 적 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
        ()){{}(<>)}

    }{}

}

메인 루프를 종료하면 모든 코드가 올바른 스택에 있습니다. 왼쪽 스택의 유일한 것은 0과 2 개의 해석 된 스택입니다. 올바른 출력을 생성하는 것은 간단합니다.

# Pop the zero
{}

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

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

12
: O 뭐 ... 좋아, 즉시 바운싱. 좋은 작업! : D
DJMcMayhem

4
이 문제를 바로 잡겠습니다 ... 통역 할 언어에 대한 통역사가 작성되었습니다. YoDawg
tisaconundrum 8

좋아요, 왜 2 자리 공감 번호 만 가지고 있습니까?
NieDzejkob

에 accumulator를 올바르게 구현하는 데 도움이됩니다 {...}. 이것은 현대 brain-flak 및 (brain-flak classic)의 올바른 동작이지만 {...}0으로 평가되는 도전 과제를 작성했습니다. 일반적으로 기술적으로 더 정확하기 때문에 원본을 유지하는 것이 좋지만이 기능을 제거함으로써 (이 도전에서는
잘못됨

@DJMcMayhem 수정되었습니다. 전체 통역사를 가상 버전의 Brain-Flak으로 이식하지 마십시오.
Nitrodon

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

언 골프 버전 : here .


7

APL (Dyalog Classic) , 146 바이트

↑⍕¨s⊣{⍎⍕1 ¯1'(s↓⍨←1)⊢⊃s' '0⊣s t←t s' 's,⍨←+/∇¨a' '⎕←+/∇¨a' '∇{×⊃s:∇⍺⍺¨a⋄0}0' '0⊣+/∇¨a'[(⊃⍵)+4×⍬≢a1↓⍵]}¨⍎∊(')',⍨'(',¨⍕¨⍳4)[0,4,⍨'([{<'⍳⍞]⊣s←⌽⎕⊣t←⍬

온라인으로 사용해보십시오!

하나의 고전이 다른 것을 해석 :)


6

파이썬 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두뇌 플래 크 소스를 파이썬으로 "컴파일"하고 파이썬을 실행하는 데 사용됩니다. (debuging에 대한 교체 exec와 함께 print상기 파이썬 코드의 목록을 얻을 수)

중첩 된 while 루프를 올바르게 들여 쓰기하면 코드에서 많은 바이트가 소모됩니다.


3

파이썬, 616 바이트

명령:

  1. 파이썬으로 실행
  2. [1,2,...]형식으로 목록을 입력 한 다음 Enter 키를 누릅니다
  3. 프로그램 붙여 넣기 / 쓰기 후 Enter를 다시 누릅니다.
  4. 끝난

기본적으로이 프로그램은 Brain-flak 코드를 재귀 적으로 중첩 된 목록으로 "컴파일"하고 해당 목록을 재귀 적으로 해석합니다. 아마도 두 가지를 결합하는 방법이있을 것입니다 ...

나중에 논리를 다시 시도하겠습니다.

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

파이썬 2 , 361 , 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.