CJam, 139 바이트
글쎄요, 이것은 느낌이 들기까지 많은 시간이 걸렸습니다. CJam 코드를 적극적으로 최적화하는 데 걸리는 시간 은 코드 크기와 관련하여 O (n) 보다 큰 것 같습니다 .
온라인으로 시도 할 수 있지만 최상의 경로가 6 회 이상인 입력의 경우 빠른 인터프리터를 사용하여 오프라인 으로 시도 해야합니다 .
박살 :
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=
확장 및 의견 :
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";
전반적으로 이것은 매우 간단한 솔루션입니다. 경로가 작동 할 때까지 0부터 시작하여 매 반복마다 증분되는 경로 번호의 기본 5 표시 숫자를 "실행"합니다. 숫자 1
- 4
작업을 위, 아래, 왼쪽 및 오른쪽으로 매핑하며 0
아무 것도 수행하지 않습니다. 경로를 사용하는 첫 번째 반복 0
은 퇴화 사례를 포착합니다. 를 포함하는 다른 모든 경로 0
는 선택되지 않은 이미 테스트 된 경로의 버전이므로 선택되지 않습니다.
상태는 가능한 최소한의 방식으로 모델링됩니다 : 시작 및 끝 마커가 제거 된 텍스트, 텍스트의 커서 위치 및 "열 메모리". 줄 바꿈은 대부분 다른 문자와 같이 취급되므로 행 개념이 없으며 커서 위치는 색인 일뿐입니다. 이로 인해 왼쪽과 오른쪽 데드가 간단하게 움직일 수 있으며, 텍스트 크기에 맞게 클램핑하여 증가 및 증가로 구현됩니다. 위아래로 이동하는 것은 조금 까다 롭지 만 여전히 관리 가능합니다.
코드 재사용은 매우 중요한 최적화 전략이었습니다. 이에 대한 예는 다음과 같습니다.
- 자체 코드를 작성하는 것보다 런타임에 아래로 이동하는 코드를 생성하는 것이 더 작은 방식으로 위로 이동하기위한 코드 작성 이것은 몇 문자 위로 이동하고 제거 / 바꾸기위한 코드를 복사하여 수행됩니다.
- "열 메모리"업데이트는 경로 논리를 연산 논리로 코딩하는 대신 3으로 나눈 경로를 기준으로 조건부로 수행됩니다. 또한
5
경로 문자열의 시작 부분에 더미 연산을 추가하여 열 메모리를 초기화 할 수 있습니다. 0
순환 배열 인덱싱으로 인해 no-op 논리도 사용 되며 5 개의 정의 된 연산 만 있습니다.
전반적으로, 나는 이것이 어떻게 나왔는지 매우 기쁘게 생각합니다. 이것은 분명히 코드 골프 답변에 들어간 가장 많은 작업입니다 (트위트에 맞는 것!?). 그러나 실행 시간은 꽤 무섭습니다. CJam은 시작하기에 가장 빠른 언어는 아니며이 알고리즘은 O (m * 5 n ) 와 같이 복잡합니다 . 여기서 m 은 입력 크기이고 n 은 출력 크기입니다. 좋은 속도는 중요하지 않습니다!