<>(()){<>((([][][][][])<(((({}){})(({})({}))[])({}(({})({}({})({}{}(<>)))))[])>{()<{}>}{})<{{}}{}>())}{}<>(<(({()(((<>))<>)}{}{<({}(([][][])((({})({}))[]{})){})>((){[]<({}{})((){[]<({}{}<>((({})({})){}{}){})(<>)>}{}){{}{}<>(<({}{}())>)(<>)}>}{}){(<{}{}{}((<>))<>>)}{}}<>)<{({}[]<({}<>)<>{(<{}>)<>{<>({}[])}{}<>({}<>)(<>)}{}>)}{}<>>)>)<>{(({}[])(){(<{}>)<><(({})[])>[][][][]{()()()()(<{}>)}{}<>}{}<>)<>}<>{}{(({})<({()<<>({}<>)>}{})>([]))((){[](<(({}()()(<>))()()()){(<{}>)<>}>)}{}<>){{}((){[]<({}())((){[]<({}())((){[]<({}())((){[]<({}())((){[]<({}())((){[]<({}())((){[](<{}<>{({}<>)<>}{}(({}))({<{}({}<>)<>>{}(<<>({}[]<>)>)}<><{({}<>)<>}>{})>)}{}){{}{}(<([])>)}>}{}){{}<>{({}<>)<>}{}((({})())<{({}[]<({}<>)<>>)}>{}){({}[]<><({}<><({()<({}[]<({}<>)<>>)>}{}<>)><>)<>({()<({}[]<({}<>)<>>)>}{}<>)>)}<>(<{({}<>)<>}>)}>}{}){{}{}(<(())>)}>}{}){(<{}{}>)<>{({}<>)<>}{}(({}))({<{}({}<>)<>>({})(<<>({}<>)>)}<><{({}<>)<>}>){{}([][][])<>(((<{}>)<>))}}>}{}){{}(<([{}])>)}>}{}){{}((<{}>))}>}{}){{}(({})(<()>)<<>{({}<>)<>}{}({}()<>)<>>)<>(<({}<>)>)<>{({}<>)<>}}{}(<({}<({}<>)<>>{})<>({}<>)>)<>(<({}())>)}{}({}<{({}[]<({}<>)<>>)}{}>){((({}[]<>){(<{}({}<>)>)}{}())<{({}()<({}<>)<>(({})[])>{[][](<{}>)}{})}{}>()){{}(<>)}}{}}{}{({}[]<[{}]>)}{}{({}[]<{}>)}{}
ลองออนไลน์!
+4 ไบต์จากการแก้ไขข้อบกพร่องด้วยเงื่อนไขใน{...}
monad และ -36 ไบต์จากสนามกอล์ฟต่างๆ
รหัส 1238 ไบต์, +1 ไบต์สำหรับการ-a
ตั้งค่าสถานะ (ซึ่งสามารถรวมกับการตั้งค่าภาษา)
ตอนนี้ประเมิน{...}
ว่าเป็นศูนย์ตามข้อกำหนดของความท้าทาย โปรดทราบว่า Brain-Flak นั้นได้ประเมิน{...}
ว่าผลรวมของการวิ่งทั้งหมดตั้งแต่วันที่ 7 พฤษภาคม 2559 การแก้ไขข้อผิดพลาดสองวันก่อนการลงแข่งขันครั้งนี้
รหัสต่อไปนี้ตีความ Brain-Flak Classic อย่างถูกต้องพร้อมกับ{...}
ผลรวมของการทำงานทั้งหมด ข้อแตกต่างระหว่างล่ามสองคนคือการจัดวางของหนึ่ง{}
nilad
<>(()){<>((([][][][][])<(((({}){})(({})({}))[])({}(({})({}({})({}{}(<>)))))[])>{()<{}>}{})<{{}}{}>())}{}<>(<(({()(((<>))<>)}{}{<({}(([][][])((({})({}))[]{})){})>((){[]<({}{})((){[]<({}{}<>((({})({})){}{}){})(<>)>}{}){{}{}<>(<({}{}())>)(<>)}>}{}){(<{}{}{}((<>))<>>)}{}}<>)<{({}[]<({}<>)<>{(<{}>)<>{<>({}[])}{}<>({}<>)(<>)}{}>)}{}<>>)>)<>{(({}[])(){(<{}>)<><(({})[])>[][][][]{()()()()(<{}>)}{}<>}{}<>)<>}<>{}{(({})<({()<<>({}<>)>}{})>([]))((){[](<(({}()()(<>))()()()){(<{}>)<>}>)}{}<>){{}((){[]<({}())((){[]<({}())((){[]<({}())((){[]<({}())((){[]<({}())((){[]<({}())((){[](<{}<>{({}<>)<>}{}(({}))({<{}({}<>)<>>{}(<<>({}[]<>)>)}<><{({}<>)<>}>{})>)}{}){{}{}(<([])>)}>}{}){{}<>{({}<>)<>}{}((({})())<{({}[]<({}<>)<>>)}>{}){({}[]<><({}<><({()<({}[]<({}<>)<>>)>}{}<>)><>)<>({()<({}[]<({}<>)<>>)>}{}<>)>)}<>(<{({}<>)<>}>)}>}{}){{}{}(<(())>)}>}{}){(<{}>)<>{({}<>)<>}{}(({}))({<{}({}<>)<>>({})(<<>({}<>)>)}<><{({}<>)<>}>{}){{}([][][])<>(((<{}>)<>))}}>}{}){{}(<([{}])>)}>}{}){{}((<{}>))}>}{}){{}(({})(<()>)<<>{({}<>)<>}{}({}()<>)<>>)<>(<({}<>)>)<>{({}<>)<>}}{}(<({}<({}<>)<>>{})<>({}<>)>)<>(<({}())>)}{}({}<{({}[]<({}<>)<>>)}{}>){((({}[]<>){(<{}({}<>)>)}{}())<{({}()<({}<>)<>(({})[])>{[][](<{}>)}{})}{}>()){{}(<>)}}{}}{}{({}[]<[{}]>)}{}{({}[]<{}>)}{}
ลองออนไลน์!
อินพุต (ไปยังตัวแปลทั้งสองตัว) เป็นโปรแกรม 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 สิ่งนี้มีซับในสีเงิน: การป้อนข้อความช่วยให้เราสามารถกำหนดความสูงของสแต็กซึ่งทำให้สิ่งต่าง ๆ ง่ายขึ้นเมื่อเราไม่สามารถเข้าถึงความสูงของสแต็กที่ไม่มี
จำนวนเต็มถูกแยกวิเคราะห์เป็นตัวเลขสองตัวในสแต็กที่สอง: หนึ่งค่าสำหรับค่าสัมบูรณ์และอีกหนึ่งสำหรับเครื่องหมาย สิ่งเหล่านี้จะถูกย้ายกลับไปที่สแต็กแรก
สแต็คที่แปลจะถูกเก็บไว้ด้านล่างรหัสในสแต็กแรกตามลำดับต่อไปนี้: ความสูงสแต็กปัจจุบัน, สแต็กปัจจุบัน, ความสูงสแต็กอื่น, สแต็กอื่น ๆ 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
>)
การเป็นตัวแทนของรหัสจะถูกย้ายกลับไปที่กองซ้าย เพื่อให้ง่ายขึ้นในภายหลังเราจะลบ 4 จากวงเล็บเปิดของ nilads เพื่อให้แต่ละการดำเนินการมีจำนวนเต็มเฉพาะจาก -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
()){{}(<>)}
}{}
}
หลังจากออกจากลูปหลักโค้ดทั้งหมดจะอยู่ในสแต็กด้านขวา สิ่งเดียวที่อยู่บนสแต็กด้านซ้ายคือศูนย์และสแต็คทั้งสองตีความ การสร้างผลลัพธ์ที่ถูกต้องเป็นเรื่องง่าย
# Pop the zero
{}
# Output current stack
{({}[]<[{}]>)}{}
# Discard other stack to avoid implicit printing
{({}[]<{}>)}{}