Điều hướng văn bản bằng các phím mũi tên


11

Lý lịch

Hầu hết các trình soạn thảo văn bản (nửa chừng) cho phép bạn điều hướng văn bản bằng các phím mũi tên. Lên và xuống cho phép bạn điều hướng các dòng, trong khi trái và phải di chuyển qua một dòng nhưng cũng quấn quanh. Hơn nữa, nếu dòng ngắn hơn vị trí X của con trỏ, con trỏ sẽ xuất hiện ở cuối dòng nhưng trở về cùng vị trí X nếu bạn tiếp tục di chuyển lên hoặc xuống. Có lẽ giải thích trực quan sau đây sẽ giúp:

Ví dụ về chuyển động

Một mẫu văn bản đơn giản có thể trông như thế này. Con trỏ sẽ được chèn giữa hai ký tự trong văn bản này hoặc ở cuối.

-----
---
------

let's put the cursor here:

X-----
---
------

move down (v):

-----
X---
------

move left (<):

-----X
---
------

v

-----
---X
------

v (notice how the X position of the cursor has been maintained)

-----
---
-----X-

^

-----
---X
------

>  (more line wrapping)

-----
---
X------

<

-----
---X
------

^ (the X-position from earlier is no longer maintained due to the left-right motion)

---X--
---
------

Các thách thức

Đưa ra một số dòng thử nghiệm ASCII, tìm đường đi ngắn nhất từ ​​vị trí bắt đầu đến vị trí kết thúc. Vị trí bắt đầu được đại diện bởi ^và vị trí kết thúc được đại diện bởi $, và sẽ chỉ có một trong số đó. Chúng không được coi là một phần của văn bản và không đóng góp vào "độ dài" của dòng đó.

Đầu vào sẽ bao gồm một số dòng văn bản không trống. Đầu ra sẽ là một chuỗi các ^v<>ký tự hiển thị một trong những đường dẫn ngắn nhất. Bạn có thể tùy ý giả sử một dòng mới bổ sung vào cuối mỗi dòng, nhưng đó không được bao gồm như là một phần của văn bản điều hướng.

Bạn có thể viết một chương trình hoặc chức năng được đặt tên. Người chiến thắng sẽ là bài nộp ngắn nhất, được đo bằng byte.

Ví dụ I / O

^Squares
are
fun$ny

vv<v  (which is better than the naive vv>>>)

Squares
^are
funny$

<vv

Alp$habet^
Song

v<^

Mary had a little lamb,
His fleece was white as snow,
And$ everywhere that ^Mary went,
The lamb was sure to go.

^^>>>>v>>>

$^degenerate case

(no output)

"Con trỏ sẽ được chèn giữa hai ký tự trong văn bản này hoặc ở cuối" - tiến hành đặt con trỏ ở đầu trong ví dụ đầu tiên
aditsu thoát vì SE là EVIL

Có hai đầu của mỗi dòng. Chỉnh sửa thành "một kết thúc."
PhiNotPi

Vim cho phép mũi tên. Tôi có một vi thực trên hộp AIX của tôi không có (Tôi đã thêm các câu lệnh bản đồ vào tệp khởi động của mình). "nửa chừng đàng hoàng" ... vâng
Jerry Jeremiah

Đầu ra của ví dụ đầu tiên cũng có thể v<vv, phải không? Hay điều đó sẽ kết thúc sau nhân vật cuối cùng trên dòng đó?
mbomb007

@ mbomb007 Nó sẽ kết thúc sau ký tự cuối cùng của dòng.
PhiNotPi

Câu trả lời:


7

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!


Nice :) Tôi cảm thấy một tội bit cho gián tiếp làm cho bạn dành rất nhiều thời gian về vấn đề này: p
aditsu bỏ vì SE là EVIL

2

Con trăn 2: 446

Q=input().split('\n');
def g(c):l=[l for l in Q if c in l][0];return Q.index(l),l.index(c)
a,b=g('^');c,d=g('$');Q=map(len,Q);Q[a]-=1;Q[c]-=1
if a==c:d-=b<d;b-=d<b
t=-1
while Q:
 l=[];T=t=t+1;x,y,z=a,b,b
 while T:l+=[T%5]*(T%5>0);T/=5
 for T in l:A=":x+=T+T-3;y=min(Q[x],z)";B="x<len(Q)-1";exec"if "+["","x"+A,B+A,"y:y=z=y-1\nelif x:x-=1;y=z=Q[x]","y<Q[x]:y=z=y+1\nelif "+B+":x+=1;y=z=0"][T]
 if(x,y)==(c,d):print''.join(' ^v<>'[x]for x in l);Q=0

Giải pháp đơn giản. Tôi đang thực hiện tìm kiếm đầu tiên. tlặp đi lặp lại trên tất cả các con đường khác nhau. Tôi chuyển đổi tthành cơ sở 5, nhưng chỉ sử dụng các mục, đó là khác không. 1là lên, 2là xuống, 3là trái và 4là phải.

Tôi giữ vị trí hiện tại của con trỏ trong 3 biến x, yz. xlà dòng, yvị trí cột và vị trí cột z'ẩn', nếu bạn đi lên hoặc xuống và dòng quá ngắn. Rất nhiều ifs quyết định, làm thế nào biến thay đổi trong một di chuyển.

Tiền xử lý thực sự dài, 4 dòng đầu tiên chỉ thực hiện nhiệm vụ này.

Các testcase dài mất một thời gian thực sự dài. Thuật toán có độ phức tạp là O (N * 5 ^ N), trong đó N là độ dài của giải pháp ngắn nhất.

Cách sử dụng: Nhập các dòng dưới dạng một chuỗi (các dòng được phân tách bằng \n) như"Alp$habet^\nSong"


1

CJam - 274

Chưa có câu trả lời? Ok, đây là một :)

qN/_{0:V;{_'^={[UVV]:B;;}{'$={[UV]:E;}{V):V;}?}?}/U):U;}/"^$"f-:,:A;{:X0=[X0=(_A=X2=_@e<\]X?}:U;{:X0=A,(=X[X0=)_A=X2=_@e<\]?}:D;{:X1=[X~;(_]{X0=[X0=(_A=_]X?}?}:L;{:X1=X0=A=={X0=A,(=X[X0=)0_]?}[X~;)_]?}:R;[[BM]]{_{0=2<E=},_{0=1=o0}{;[{"U^DvL<R>"2/\f{[~@1/~@\+@@~\]}~}/]1}?}g;

Hãy dùng thử tại http://cjam.aditsu.net/ ... ngoại trừ ví dụ Mary hoặc một cái gì đó có kích thước đó, có thể bạn sẽ muốn trình thông dịch java .


1
WTF? 274 !!!!!!
Tối ưu hóa

@Optimizer hahaha, tốt, tôi đã lãng phí đủ thời gian cho nó, hãy tiếp tục và chơi golf nhiều hơn nếu bạn muốn: p
aditsu bỏ vì SE là EVIL
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.