<#; "#: ={},>
}=}(.);("@
Một người cộng tác khác với @ MartinBüttner, người thực sự đã làm hầu hết tất cả các môn đánh gôn cho môn này. Bằng cách cải tiến thuật toán, chúng tôi đã cố gắng giảm kích thước chương trình xuống một chút!
Hãy thử trực tuyến!
Giải trình
Một mồi nhanh Labrinth:
Labyrinth là một ngôn ngữ 2D dựa trên ngăn xếp. Có hai ngăn xếp, một ngăn xếp chính và phụ, và xuất hiện từ một ngăn xếp trống mang lại số không.
Tại mỗi ngã ba, nơi có nhiều đường dẫn cho con trỏ lệnh di chuyển xuống, đỉnh của ngăn xếp chính được kiểm tra để xem nơi tiếp theo sẽ đi. Tiêu cực là rẽ trái, không là thẳng về phía trước và tích cực là rẽ phải.
Hai ngăn xếp của các số nguyên chính xác tùy ý không linh hoạt về các tùy chọn bộ nhớ. Để thực hiện đếm, chương trình này thực sự sử dụng hai ngăn xếp như một cuộn băng, với việc chuyển một giá trị từ ngăn xếp này sang ngăn xếp khác giống như di chuyển một con trỏ bộ nhớ sang trái / phải bởi một ô. Mặc dù vậy, nó không hoàn toàn giống như vậy, vì chúng ta cần phải kéo một bộ đếm vòng lặp với chúng ta trên đường lên.
Trước hết, phần cuối <
và >
một trong hai bật một phần bù và xoay hàng mã bù đi một bên trái hoặc phải. Cơ chế này được sử dụng để làm cho mã chạy trong một vòng lặp - <
bật số 0 và xoay hàng hiện tại sang trái, đặt IP ở bên phải mã và >
bật số 0 khác và sửa lại hàng.
Đây là những gì xảy ra mỗi lần lặp, liên quan đến sơ đồ trên:
[Section 1]
,} Read char of input and shift to aux - the char will be used as a counter
to determine how many elements to shift
[Section 2 - shift loop]
{ Shift counter from aux
" No-op at a junction: turn left to [Section 3] if char was EOF (-1), otherwise
turn right
( Decrement counter; go forward to [Section 4] if zero, otherwise turn right
= Swap tops of main and aux - we've pulled a value from aux and moved the
decremented counter to aux, ready for the next loop iteration
[Section 3]
@ Terminate
[Section 4]
; Pop the zeroed counter
) Increment the top of the main stack, updating the count of the number of times
we've seen the read char
: Copy the count, to determine how many chars to output
[Section 5 - output loop]
#. Output (number of elements on stack) as a char
( Decrement the count of how many chars to output; go forward to [Section 6]
if zero, otherwise turn right
" No-op
[Section 6]
} Shift the zeroed counter to aux
[Section 7a]
This section is meant to shift one element at a time from main to aux until the main
stack is empty, but the first iteration actually traverses the loop the wrong way!
Suppose the stack state is [... a b c | 0 d e ...].
= Swap tops of main and aux [... a b 0 | c d e ...]
} Move top of main to aux [... a b | 0 c d e ...]
#; Push stack depth and pop it (no-op)
= Swap tops of main and aux [... a 0 | b c d e ...]
Top is 0 at a junction - can't move
forwards so we bounce back
; Pop the top 0 [... a | b c d e ... ]
The net result is that we've shifted two chars from main to aux and popped the
extraneous zero. From here the loop is traversed anticlockwise as intended.
[Section 7b - unshift loop]
# Push stack depth; if zero, move forward to the <, else turn left
}= Move to aux and swap main and aux, thus moving the char below (stack depth)
to aux
; Pop the stack depth