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";
โดยรวมแล้วนี่เป็นคำตอบที่ค่อนข้างตรงไปตรงมา มัน "ดำเนินการ" ตัวเลขของการเป็นตัวแทนฐาน -5 ของหมายเลขเส้นทางที่เพิ่มขึ้นทุกการทำซ้ำเริ่มต้นด้วย 0 จนกระทั่งเส้นทางการทำงาน ตัวเลข1- 4แมปการดำเนินการขึ้นลงซ้ายและขวาและ0ไม่ทำอะไรเลย การวนซ้ำครั้งแรกโดยใช้เส้นทางที่เพิ่ง0จับตัวเคสที่เสื่อม เส้นทางอื่น ๆ ทั้งหมดที่มี a 0จะไม่ถูกเลือกเนื่องจากเป็นเพียงรุ่นของเส้นทางที่ผ่านการทดสอบแล้วและไม่มีการเพิ่ม
สถานะถูกจำลองในแบบที่เรียบง่ายที่สุดเท่าที่จะทำได้: ข้อความที่มีเครื่องหมายเริ่มต้นและสิ้นสุดถูกลบตำแหน่งเคอร์เซอร์ในข้อความและ "หน่วยความจำคอลัมน์" ขึ้นบรรทัดใหม่ส่วนใหญ่ถือว่าเหมือนตัวละครอื่น ๆ ดังนั้นจึงไม่มีแนวคิดของแถวและตำแหน่งเคอร์เซอร์เป็นเพียงดัชนี สิ่งนี้ทำให้การย้ายไปทางซ้ายและขวาตายง่ายซึ่งเพิ่งถูกนำมาใช้เป็นการลดลงและเพิ่มขึ้น (โดยยึดขนาดของข้อความ) การเลื่อนขึ้นและลงนั้นค่อนข้างยุ่งยาก แต่ก็ยังสามารถจัดการได้
การใช้รหัสซ้ำเป็นกลยุทธ์การเพิ่มประสิทธิภาพที่สำคัญ ตัวอย่างของสิ่งนี้รวมถึง:
- การเขียนโค้ดเพื่อเลื่อนขึ้นในลักษณะที่เล็กกว่าเพื่อสร้างโค้ดสำหรับการเลื่อนลงที่รันไทม์มากกว่าที่จะเขียนโค้ดของตัวเอง สิ่งนี้ทำได้โดยการคัดลอกรหัสเพื่อเลื่อนขึ้นและนำออก / แทนที่อักขระสองสามตัว
- การอัพเดต "หน่วยความจำคอลัมภ์" นั้นทำได้ตามเงื่อนไขโดยใช้หลักพา ธ หารด้วย 3 แทนที่จะเป็นโค๊ดในตรรกะของการดำเนินการ สิ่งนี้ยังช่วยให้การเริ่มต้นของหน่วยความจำคอลัมน์โดยการเพิ่มการ
5ดำเนินการจำลองไปยังจุดเริ่มต้นของสตริงเส้นทางซึ่งเกิดขึ้นกับการใช้0ตรรกะ no-op เนื่องจากการทำดัชนีอาร์เรย์แบบวงกลมและมีการดำเนินการที่กำหนดไว้เพียง 5 รายการ
โดยรวมแล้วฉันมีความสุขมากกับสิ่งที่เกิดขึ้น นี่เป็นงานที่ดีที่สุดที่ฉันเคยใส่ลงไปในคำตอบของกอล์ฟ (สำหรับบางสิ่งที่เหมาะกับทวีต!?) ถึงแม้ว่าเวลาในการทำงานจะค่อนข้างแย่ CJam ไม่ใช่ภาษาที่เร็วที่สุดที่จะเริ่มต้นด้วยและอัลกอริธึมนี้มีความซับซ้อนของบางอย่างเช่นO (m * 5 n )โดยที่mคือขนาดของอินพุตและnคือขนาดของเอาต์พุต ความเร็วที่ดีไม่นับ!