CJam, 139 byte
Vâng, điều này đã mất nhiều giờ để đi đến một cái gì đó cảm thấy được thực hiện. Cảm giác như thời gian cần thiết để tối ưu hóa mạnh mẽ mã CJam là một cái gì đó lớn hơn O (n) đối với kích thước của mã ...
Bạn có thể thử trực tuyến , nhưng đối với bất kỳ đầu vào nào có đường dẫn tốt nhất có ít nhất 6 thao tác hoặc hơn, có lẽ bạn nên thử ngoại tuyến với trình thông dịch nhanh hơn.
Squished:
q_'$-_'^-:T;'^#\'^-'$#W{)2$5Y$5b+{:D[L"_T<W%_N#)_@>N+N#X-Ue>+-"_"W%-U"--2'<t2'>t'++'(')]=~0e>T,e<D3/1$T<N\+W%N#X?:X;}/2$-}g5b{" ^v<>"=}%]W=
Mở rộng và bình luận:
q "Read the input";
_'$- "Remove the end marker";
_'^-:T; "Remove the start marker and save the text";
'^# "With only the end marker removed, locate the start marker";
\'^-'$# "With only the start marker removed, locate the end marker";
W "Initialize the path number to -1";
{ "Do...";
) "Increment the path number";
2$ "Initialize the cursor position to that of the start marker";
5Y$5b+ "Convert the path number to base 5, then add a leading 5
(the leading 5 will act to initialize the column memory)";
{:D "For each digit in the path digit string:";
[ "Begin cases:";
L "0: Do nothing";
"_T<W%_N#)_@>N+N#X-Ue>+-"
"REFS: [ 1 ][ 2 ][ 3 ]45
1: [1] Calculate the distance to the end of the previous
line (0 if no such line)
[2] Calculate the length of the previous line (0 if
no such line)
[3] Calculate the distance to move backwards in the
previous line as the maximum of the length of the
previous line minus the column memory and 0
[4] Calculate the total distance to move as the sum
of [1] and [3]
[5] Subtract [4] from the cursor position";
_"W%-U"- "2: Start with a base of the logic of case 1, but with a
few operations adjusted.";
-2'<t2'>t " [1] Calculate the distance to the *start* of the
*next* line (0 if no such line)
[2] Calculate the length of the *next* line (0 if no
such line)
[3] Calculate the distance to move *forwards* in the
*next* line as the *minimum* of the length of the
*next line* and *the column memory*
[4] Calculate the total distance to move as the sum
of [1] and [3]";
'++ " [5] *Add* [4] *to* the cursor position";
'( "3: Decrement the cursor position";
') "4: Increment the cursor position";
]=~ "Execute the case corresponding to the path digit mod 5";
0e>T,e< "Clamp the cursor position to [0, text length]";
D3/ "Check if the path digit is not 0, 1, or 2...";
1$T<N\+W%N# "Calculate the current column";
X?:X; "If the above check succeeded, update the column memory";
}/ "End for each";
2$- "Subtract the end marker position from the cursor position";
}g "... While the above subtraction is nonzero";
5b "Convert the path number to base 5";
{" ^v<>"=}% "Map each digit in the path string to its operation symbol";
]W= "Clean up";
Nhìn chung, đây là một giải pháp khá đơn giản. Nó "thực thi" các chữ số của biểu diễn cơ sở-5 của một số đường dẫn được tăng lên mỗi lần lặp, bắt đầu bằng 0, cho đến khi một đường dẫn hoạt động. Các chữ số 1- 4ánh xạ tới các hoạt động lên, xuống, trái và phải và 0không làm gì cả. Lặp lại đầu tiên bằng cách sử dụng một đường dẫn chỉ 0bắt trường hợp suy biến. Tất cả các đường dẫn khác chứa a 0không bao giờ được chọn vì chúng chỉ là phiên bản của các đường dẫn đã được kiểm tra có thêm không có op-op.
Trạng thái được mô hình hóa theo cách tối giản nhất có thể: văn bản có dấu bắt đầu và dấu kết thúc bị xóa, vị trí con trỏ trong văn bản và "bộ nhớ cột". Các dòng mới hầu hết được xử lý như bất kỳ ký tự nào khác, vì vậy không có khái niệm về một hàng và vị trí con trỏ chỉ là một chỉ mục. Điều này làm cho việc di chuyển trái và phải trở nên đơn giản, được thực hiện dưới dạng giảm và tăng (với việc kẹp vào kích thước của văn bản). Di chuyển lên xuống là một chút khó khăn hơn, nhưng vẫn có thể quản lý được.
Tái sử dụng mã là một chiến thuật tối ưu hóa khá quan trọng. Ví dụ về điều này bao gồm:
- Viết mã để di chuyển lên theo cách nhỏ hơn để tạo mã để di chuyển xuống trong thời gian chạy hơn là viết mã của chính nó. Điều này được thực hiện bằng cách sao chép mã để di chuyển lên và xóa / thay thế một vài ký tự.
- Cập nhật "bộ nhớ cột" được thực hiện có điều kiện dựa trên chữ số đường dẫn chia cho 3 thay vì được mã hóa thành logic của thao tác. Điều này cũng cho phép khởi tạo bộ nhớ cột bằng cách thêm một
5thao tác giả vào đầu chuỗi đường dẫn, điều này cũng xảy ra để sử dụng 0logic no-op do lập chỉ mục mảng tròn và chỉ có 5 thao tác được xác định.
Nhìn chung, tôi rất hài lòng với cách thức này xuất hiện. Đây chắc chắn là công việc nhiều nhất tôi đã đưa vào một câu trả lời golf mã cho đến nay (đối với một cái gì đó phù hợp với một tweet!?). Thời gian chạy là khá nhiều, mặc dù. CJam không chính xác là ngôn ngữ nhanh nhất để bắt đầu và thuật toán này có độ phức tạp giống như O (m * 5 n ) , trong đó m là kích thước của đầu vào và n là kích thước của đầu ra. Tốc độ tốt không tính!