Con đường tự tránh ngắn nhất được đưa ra một chuỗi các lượt


15

Viết chương trình hoặc chức năng, đưa ra một chuỗi không trống của rẽ phải hoặc trái, đưa ra độ dài của con đường tự tránh ngắn nhất trên mạng 2D với các lượt đó.

Đầu vào phải được lấy dưới dạng một chuỗi, với mỗi ký tự được Rhoặc Llần lượt sang phải hoặc rẽ trái.

Đầu ra phải là một số nguyên, độ dài của đường dẫn ngắn nhất với các lượt đã cho.

Đây là một golf gode - chiến thắng mã ngắn nhất.

Thí dụ

Đưa ra đầu vào

LLLLLLLLLLRRL

Con đường ngắn nhất là như sau (bắt đầu từ #):

+-+-+-+-+-+-+
|           |  
+ . + +-+-+ +
|   | |   | |  
+ +-+ + #-+ +
| |   |     |  
+ +-+ +-+-+-+
|   |          
+-+-+ . . . .

Và tổng chiều dài của đường dẫn này là 29(tính -s và |s, không phải +s).

Các trường hợp thử nghiệm

L 2
RRRRRRRRRR 23
LRRLRLRRRRL 15
LLRRLRRRRLLL 17
LLRRRRRRLLLL 21
LLLLRLLRRLLRL 16
LRLRLRLLRLRRL 14
RLLRRRRLLRRLRL 17
RRRRLLRLLLRLRL 20
LLLLRRLRLRRRLRL 19
RRRLRRRLRRLRLRL 20

Tự tránh ngay cả ở các góc (ví dụ: đi về phía nam trên Main về phía Elm và quay về hướng đông vào Elm và sau đó đi về phía bắc trên Main về phía Elm và quay về hướng tây vào Elm là không nên)?
msh210

2
@ msh210 có, nó không thể truy cập cùng một điểm hai lần, ngay cả trên một góc.
cardboard_box

Câu trả lời:


8

Prolog, 284 byte

e(S,[0|X]):-e(S,X).
e([A|S],[A|X]):-S=X;e(S,X).
v(X/Y,76,Y/Z):-Z is -X.
v(X/Y,82,Z/X):-Z is -Y.
v(D,0,D).  
c([],0/0-0/1,[0/0]).
c([H|T],K/L-D/E,[K/L|C]):-c(T,I/J-X/Y,C),v(X/Y,H,D/E),K is I+X,L is J+Y,\+member(K/L,C).
n(X):-X=0;n(Y),X#=Y+1.
p(S,L):-n(L),length(X,L),e([0|S],X),c(X,_,_).

Đây là một tuyên bố khá đơn giản về thuật toán và khá kém hiệu quả (không phải tất cả các trường hợp thử nghiệm đều chạy trong thời gian hợp lý, mặc dù hầu hết đã làm). Nó hoạt động thông qua việc tạo ra tất cả các độ dài có thể cho đầu ra từ 1 trở lên ( n); tạo ra tất cả các chuỗi có thể của trái / tiến / phải của độ dài đó phù hợp với đầu vào (được thực hiện trong e; đường dẫn mới được gọi X); sau đó kiểm tra đường dẫn đầu tiên như vậy có hợp lệ không ( c, gọi vào vđể xử lý các tác động của rẽ trái và phải trên các đồng bằng x và y). Độ dài trả về là đầu ra đầu tiên nhìn thấy trongL. .

Không có nhiều cách chơi golf ở đây, nhưng có một số. nđược thực hiện với một bộ giải ràng buộc vì nó cho phép loại bỏ nhiều khoảng trắng hơn mà không gây nhầm lẫn cho trình phân tích cú pháp; điều này có thể yêu cầu GNU Prolog được sử dụng, không chắc về điều đó. (Tôi không thể làm tương tự cvì nó cần xử lý các số âm.) Việc thực hiện ecó hiệu quả thấp hơn đáng kể so với yêu cầu, thông qua việc khớp danh sách theo nhiều cách; hiệu quả hơn e([],[]).sẽ dài hơn sáu byte (nó sẽ cho phép S=X;loại bỏ dòng 2, nhưng đó chỉ là mức tăng bốn so với mất mười). Để cho phép tôi khớp toàn bộ tọa độ và chỉ đường, hoặc chỉ một phần, tôi đại diện cho chúng là X/Y(tức là một AST không được đánh giá, có thể được khớp trên), cho phép tôi sử dụng ký hiệu infix.

Prolog, 256 byte, quá kém hiệu quả để dễ dàng kiểm tra

Tất nhiên, vì đây là Prolog, nhiều hàm có thể đảo ngược, ví dụ ccó thể được sử dụng để tạo tất cả các đường dẫn từ gốc đến một cặp tọa độ cụ thể. Ngoài ra, ctự nhiên tạo ra từ ngắn nhất đến dài nhất. Điều này có nghĩa là thay vì yêu cầu độ dài tối thiểu một cách rõ ràng, chúng ta chỉ có cthể tạo tất cả các đường dẫn đi bất cứ đâu , sau đó tìm đường dẫn đầu tiên phù hợp với đầu vào:

e(S,[0|X]):-e(S,X).
e([A|S],[A|X]):-S=X;e(S,X).
v(X/Y,76,Y/Z):-Z is -X.
v(X/Y,82,Z/X):-Z is -Y.
v(D,0,D).
c([],0/0-0/1,[0/0]).
c([H|T],K/L-D/E,[K/L|C]):-c(T,I/J-X/Y,C),v(X/Y,H,D/E),K is I+X,L is J+Y,\+member(K/L,C).
p(S,L):-c(X,_,_),length(X,L),e([0|S],X).

Điều này có hiệu suất theo cấp số nhân (O (3 n ), trong đó n là đầu ra). Tuy nhiên, tôi đã quản lý để xác minh nó trong một số thử nghiệm nhỏ hơn (mất khoảng 7 giây để xuất 14 và khoảng 20 đến đầu ra 15, trên máy tính của tôi).


Tôi không thể làm điều này để làm việc trên TIO , nhưng tôi có thể đang làm điều gì đó ngớ ngẩn.
Peter Kagey

@PeterKagey Tôi không biết nhiều prolog, nhưng tôi nghĩ hoạt động. Đối với đầu vào "LRRLRLRRRRL"
H.PWiz

4

Bình thường , 36 byte

ff{I.u+NYY0f>r8YlQ.C+1*M._m^.j)hCdQT

Hãy thử trực tuyến!

Điều này khá chậm, nhưng nó hoạt động, và nó đủ nhanh cho các đầu vào ngắn.

Chương trình hoạt động bằng cách biểu diễn các hướng là các đơn vị phức (1, -1, i, -i) và các điểm dưới dạng số phức. Đầu tiên tôi chuyển đổi danh sách các ngã rẽ thành một danh sách các hướng, sau đó tạo tất cả danh sách n bước, lọc cho những người có ít nhất một bước giữa mỗi lượt và chuyển đổi các hướng thành danh sách các điểm được truy cập và kiểm tra xem danh sách đó có phải là độc nhất. Tôi tăng n trong một vòng lặp cho đến khi tôi thành công.

Ánh xạ tới các số phức:

m^.j)hCdQ
m       Q    Map over the input
      Cd     Convert to ASCII codepoint
     h       Increment
 ^.j)        Raise i to that power.

Kể từ khi Lcó mã số ASCII 76 và Rcó mã số ASCII 82, bản đồ này Lđến iRđi -i.

Bản đồ theo hướng tuyệt đối:

+1*M._ ...
    ._      Form all prefixes
  *M        Map each to its product
+1          Add the first direction, before any turns

Biểu mẫu danh sách gồm n bước với ít nhất 1 bước giữa mỗi lượt

f>r8YlQ.C ... T
       .C     T    Form all list of T steps
f                  Filter for lists where
  r8Y              Run length encoding of list
 >   lQ            With the first len(input) removed
                   is nonempty

Cần có thêm một chuyển động so với các lượt trong đầu vào. Mỗi chuyển động theo một hướng khác nhau, do đó, mã hóa chiều dài chạy phải dài hơn đầu vào.

Bản đồ đến các điểm đã truy cập:

.u+NYY0  ...
.u   Y0   Reduce the following function over
          the list of steps, starting at 0.
          Return all intermediates.
  +NY     Add the new step to the current position.

Bộ lọc trên không tự giao nhau:

f{I ...
f     Filter on
  I   Invariant under
 {    Deduplication

Tìm người đầu tiên Tnơi điều này thành công : f.

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.