<>(()){<>((([][][][][])<(((({}){})(({})({}))[])({}(({})({}({})({}{}(<>)))))[])>{()<{}>}{})<{{}}{}>())}{}<>(<(({()(((<>))<>)}{}{<({}(([][][])((({})({}))[]{})){})>((){[]<({}{})((){[]<({}{}<>((({})({})){}{}){})(<>)>}{}){{}{}<>(<({}{}())>)(<>)}>}{}){(<{}{}{}((<>))<>>)}{}}<>)<{({}[]<({}<>)<>{(<{}>)<>{<>({}[])}{}<>({}<>)(<>)}{}>)}{}<>>)>)<>{(({}[])(){(<{}>)<><(({})[])>[][][][]{()()()()(<{}>)}{}<>}{}<>)<>}<>{}{(({})<({()<<>({}<>)>}{})>([]))((){[](<(({}()()(<>))()()()){(<{}>)<>}>)}{}<>){{}((){[]<({}())((){[]<({}())((){[]<({}())((){[]<({}())((){[]<({}())((){[]<({}())((){[](<{}<>{({}<>)<>}{}(({}))({<{}({}<>)<>>{}(<<>({}[]<>)>)}<><{({}<>)<>}>{})>)}{}){{}{}(<([])>)}>}{}){{}<>{({}<>)<>}{}((({})())<{({}[]<({}<>)<>>)}>{}){({}[]<><({}<><({()<({}[]<({}<>)<>>)>}{}<>)><>)<>({()<({}[]<({}<>)<>>)>}{}<>)>)}<>(<{({}<>)<>}>)}>}{}){{}{}(<(())>)}>}{}){(<{}{}>)<>{({}<>)<>}{}(({}))({<{}({}<>)<>>({})(<<>({}<>)>)}<><{({}<>)<>}>){{}([][][])<>(((<{}>)<>))}}>}{}){{}(<([{}])>)}>}{}){{}((<{}>))}>}{}){{}(({})(<()>)<<>{({}<>)<>}{}({}()<>)<>>)<>(<({}<>)>)<>{({}<>)<>}}{}(<({}<({}<>)<>>{})<>({}<>)>)<>(<({}())>)}{}({}<{({}[]<({}<>)<>>)}{}>){((({}[]<>){(<{}({}<>)>)}{}())<{({}()<({}<>)<>(({})[])>{[][](<{}>)}{})}{}>()){{}(<>)}}{}}{}{({}[]<[{}]>)}{}{({}[]<{}>)}{}
온라인으로 사용해보십시오!
{...}
모나드 의 조건으로 버그를 수정하여 +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
{({}[]<{}>)}{}