Tìm kiếm Poly Nemo!


11

Ôi không! Nemo, con cá hề nhỏ của chúng ta bị lạc trong đại dương ASCII này và cha Marlin đang cố gắng tìm anh ta.

Nhiệm vụ của bạn là đưa Marlin đến Nemo một cách an toàn. Nhưng hãy cẩn thận, chúng tôi có một Bruce điên cuồng cho ăn, vì vậy tốt hơn nên tránh anh ta bằng mọi giá!

Chi tiết

Bạn được cung cấp một lưới đại dương ASCII hình chữ nhật chỉ chứa các bảng chữ cái chữ thường a-z. Đại dương này sẽ có nemo, marlinbrucebên trong nó dưới dạng một polyomino liên tục, luôn bắt đầu từ tế bào hàng đầu trong cột đầu tiên của polyomino. Vì vậy, ví dụ, trong số tất cả các tetrominos có thể, những cái hợp lệ được liệt kê trong đoạn trích dưới đây

Nhưng các hình thức như thế này là không hợp lệ và sẽ không có mặt trong đầu vào:

omen

ne
mo

nem
o

o
m
en

nem
 o

n
eo
m

Cuối cùng, nhiệm vụ của bạn là tìm một đường dẫn từ ô marlinpolyomino đến ô nemopolyomino để đảm bảo rằng bất kỳ ô nào trong đường dẫn của bạn không liền kề với ô brucepolyomino. Đầu ra của bạn nên thay thế tất cả các bảng chữ cái không phải là một phần của marlinô, nemolát và đường dẫn kết nối cả hai với một ký tự từ phạm vi ASCII có thể in (bao gồm cả khoảng trắng) ngoài chữ thường a-z.

Thí dụ

Nếu đại dương đầu vào như sau:

oxknvvolacycxg
xmliuzsxpdzkpw
warukpyhcldlgu
tucpzymenmoyhk
qnvtbsalyfrlyn
cicjrucejhiaeb
bzqfnfwqtrzqbp
ywvjanjdtzcoyh
xsjeyemojwtyhi
mcefvugvqabqtt
oihfadeihvzakk
pjuicqduvnwscv

(với 3 polyominos là:

...n..........
.mli..........
.ar...........
..............
....b.........
....ruce......
..............
.....n........
.....emo......
..............
..............
..............

)

Sau đó, một giải pháp hợp lệ có thể trông giống như:

...n..........
.mli..........
.ar...........
.u............
.n............
.i............
.z............
.wvjan........
.....emo......
..............
..............
..............

Đoạn trích bên dưới có thêm một vài ví dụ:

Ghi chú

  • Lưới điện sẽ luôn luôn là một hình chữ nhật hoàn hảo và sẽ chứa chỉ có một gạch polyomino của nemo, marlinbruce.
  • Đường dẫn của bạn không được đi qua brucehoặc bất kỳ ô nào trong 4 ô liền kề (lên, xuống, trái và phải) của bất kỳ ô nào trong bruceô.
  • Nó luôn được đảm bảo rằng sẽ có ít nhất một đường dẫn hợp lệ từ marlinđến nemo.
  • Không có yêu cầu về một con đường ngắn nhất ở đây, vì vậy hãy đi!
  • Mặc dù bạn không phải tìm đường đi ngắn nhất, bất kỳ ô nào trong đường dẫn (đường dẫn không bao gồm marlin hoặc nemo) không thể liền kề với hơn hai ô khác trong đường dẫn.
  • Con đường không nên đi qua marlinhoặc nemogạch, vì nó sẽ khiến những con cá nhỏ bối rối trong việc chọn hướng.
  • Như thường lệ, bạn có thể viết chương trình hoặc hàm, lấy đầu vào qua STDIN (hoặc tương đương gần nhất), tham số dòng lệnh hoặc tham số hàm và tạo đầu ra thông qua STDOUT (hoặc tương đương gần nhất), giá trị trả về hoặc tham số hàm (out).
  • Nếu đầu vào nhiều dòng là không thể, thì bạn có thể giả sử rằng lưới được nối bởi |ký tự thay vì \n. Bạn cũng có thể lấy đầu vào là một mảng của các hàng lưới.

Đây là mã golf, vì vậy, mục nhập ngắn nhất trong byte sẽ thắng.


Con đường có thể đi qua marlin (hoặc nemo)? sẽ giải pháp trên vẫn có giá trị nếu kso với ltrong marlin thể nhìn thấy? (thực hiện đường dẫn từ n trong marlin đến nemo)
KSab

@KSab Tôi sẽ nói không vì nó sẽ gây nhầm lẫn với marlin :)
Trình tối ưu hóa

Câu trả lời:


4

Matlab 560

560 byte khi loại bỏ tất cả các khoảng trống không cần thiết, tất cả dấu chấm phẩy và tất cả các bình luận. Có thể chơi gôn nhiều hơn nhưng tôi thấy mệt ngay bây giờ (có thể là ngày mai ...) Chúc mọi người ngủ ngon.

PS: Tôi giả sử rằng đường dẫn phải có kết nối 4 lân cận ('+').

function c(A)
Z = [0,1,0;1,1,1;0,1,0];
Br = q('bruce');
Bn = conv2(Br,ones(3),'s')>0;
Ne = q('nemo');
Ma = q('marlin');
%construct path marlin to nemo
U=Ma>0;M=A*Inf;
M(U)=0;
for k=1:2*sum(size(A))%upper bound for path length
    %expand
    V=imdilate(U,Z);
    V(Bn)=0;
    M(V-U==1)=k;
    U=V;
    %disp(M)
end
%go back from nemo to marlin
Pr=reshape(1:numel(A),size(A));
[i,j]=find(Ne);
m=M(i(1),j(1));%value
P=A*0;%path image
P(i(1),j(1))=1;
for k=m:-1:1
    %find neighbour of (i(1),j(1)) with value m-1
    U=imdilate(P,Z);
    F = M==k;
    G = F&U;
    mask = Pr == min(Pr(F & U));
    P(mask)=1; 
end
A(~P & ~Ma & ~Ne)='.';
disp(A)



    function M = q(s)%find string in matrix, A ascii, M mask
        M = A*0;
        m=numel(s);
        N = M+1;%all neighbours
        for k=1:m;
            M(A==s(k) & N)=k;%only set the ones that were in the neighbourhood of last
            L=M==k;
            N=imdilate(L,Z);
        end
        for k=m:-1:2
            %set all that are not neighbour to next higher highest to zero
            L=M==k;
            N=imdilate(L,Z);
            M(M==k-1 & ~N)=0;
        end
    end


end

Chức năng gọi: (dòng mới không cần thiết)

c(['oxknvvolacycxg',
'xmliuzsxpdzkpw',
'warukpyhcldlgu',
'tucpzymenmoyhk',
'qnvtbsalyfrlyn',
'cicjrucejhiaeb',
'bzqfnfwqtrzqbp',
'ywvjanjdtzcoyh',
'xsjeyemojwtyhi',
'mcefvugvqabqtt',
'oihfadeihvzakk',
'pjuicqduvnwscv']);

Đầu ra:

...n..........
.mli..........
.ar...........
..c...........
..v...........
..c...........
..q...........
..vjan........
.....emo......
..............
..............
..............

Làm thế nào nó hoạt động

Trích xuất tên

Phần đầu tiên là trích xuất các tên nemo, ví dụ , được thực hiện bởi hàm q(). Hàm đầu tiên đánh dấu mọi thứ là 0, sau đó xuất hiện chữ cái đầu tiên của tên là 1, sau đó là chữ cái thứ hai như 2thể có một 1trong vùng lân cận, sau đó là chữ cái thứ ba, v.v. Sau đó nên trong trường hợp nemochỉ có một 4. Từ đó chúng tôi đi ngược lại cho đến khi chúng tôi tìm thấy 1một lần nữa và sau đó xóa tất cả các số khác lớn hơn, vì vậy chúng tôi lấy lại một mặt nạ đẹp trong đó các chữ cái nemođược che dấu. Chúng tôi làm điều này cho cả ba tên, và sau đó có thể tiến hành tìm đường dẫn.

Tìm đường

Chúng tôi bắt đầu tại các vị trí của Marlins và gửi sóng xung kích từng bước "hình ảnh". Trong mỗi bước, chúng tôi tăng bộ đếm khoảng cách và đánh dấu 'pixel' dưới mặt sóng với khoảng cách hiện tại. (Vì nó thường được thực hiện với các thuật toán đường đi ngắn nhất.) Mặt sóng này rõ ràng bị chặn bởi khu vực của Bruce, do đó nó sẽ chảy xung quanh anh ta. Bước này được lặp lại cho đến khi đạt đến giới hạn trên. Giới hạn trên (thừa nhận rất lỏng lẻo) này hiện là chu vi của 'hình ảnh' (các đường dẫn ngắn nhất sẽ ngắn hơn trong mọi trường hợp). Trong trường hợp thử nghiệm, nó trông giống như thế này:

 2 1 1  0  1  2  3  4  5  6  7  8  9 10
 1 0 0  0  1  2  3  4  5  6  7  8  9 10
 1 0 0  1  2  3  4  5  6  7  8  9 10 11
 2 1 1  _  _  _  5  6  7  8  9 10 11 12
 3 2 2  _  _  _  _  _  _  9 10 11 12 13
 4 3 3  _  _  _  _  _  _ 10 11 12 13 14
 5 4 4  _  _  _  _  _  _ 11 12 13 14 15
 6 5 5  6  7  8  9 10 11 12 13 14 15 16
 7 6 6  7  8  9 10 11 12 13 14 15 16 17
 8 7 7  8  9 10 11 12 13 14 15 16 17 18
 9 8 8  9 10 11 12 13 14 15 16 17 18 19
10 9 9 10 11 12 13 14 15 16 17 18 19 20

Bây giờ bắt đầu ở nemopixel và giảm bộ đếm khoảng cách trong mỗi bước và thêm một hàng xóm với khoảng cách thấp hơn tiếp theo (theo bản đồ khoảng cách mà chúng tôi đã tính toán trước đó) vào đường dẫn của chúng tôi.


3

Con trăn 2 - 658

Rất rất không hiệu quả cả về thời gian và bộ nhớ. Hàm để xác định các mẫu là hàm đệ quy S và hàm để tìm các đường dẫn là C, về cơ bản là một triển khai A * không hiệu quả khủng khiếp.

G=input().split('\n')
R=range
S=lambda g,x,y,s,B:[[(x,y)]+r for a,b in[(-1,0),(0,-1),(0,1),(1,0)]for r in S(g,x+a,y+b,s[1:],B)if B(x,y)and s[0]==g[y][x]]if s else[[]]
C=lambda l,N,B:[i for i in l if i[-1]in N]or C([i+[(i[-1][0]+c,i[-1][1]+d)]for i in l for c,d in [(-1,0),(0,-1),(0,1),(1,0)]if all(1<abs(i[-1][0]+c-a)or 1<abs(i[-1][1]+d-b)for a,b in B)],N,B)
X,Y=len(G[0]),len(G)
N,M,B=[filter(list,[S(G,s,t,e,lambda a,b:0<=a<X and 0<=b<Y and Y*(a-s)+b-t>=0)for s in R(X)for t in R(Y)])[0][0]for e in["nemo","marlin","bruce"]]
print'\n'.join(''.join(G[y][x]if(x,y)in N+M+min([C([[k]],N,B)[0]for k in M],key=lambda i:len(i))else'.'for x in R(X))for y in R(Y))

Để thử nghiệm, hãy sử dụng cái này ít hơn (một chút) ít tính toán hơn (tính toán đường đi một lần thay cho mỗi ô)

G=input().split('\n')
R=range
S=lambda g,x,y,s,B:[[(x,y)]+r for a,b in[(-1,0),(0,-1),(0,1),(1,0)]for r in S(g,x+a,y+b,s[1:],B)if B(x,y)and s[0]==g[y][x]]if s else[[]]
C=lambda l,N,B:[i for i in l if i[-1]in N]or C([i+[(i[-1][0]+c,i[-1][1]+d)]for i in l for c,d in [(-1,0),(0,-1),(0,1),(1,0)]if all(1<abs(i[-1][0]+c-a)or 1<abs(i[-1][1]+d-b)for a,b in B)],N,B)
X,Y=len(G[0]),len(G)
N,M,B=[filter(list,[S(G,s,t,e,lambda a,b:0<=a<X and 0<=b<Y and Y*(a-s)+b-t>=0)for s in R(X)for t in R(Y)])[0][0]for e in["nemo","marlin","bruce"]]
s=N+M+min([C([[k]],N,B)[0]for k in M],key=lambda i:len(i))
print'\n'.join(''.join(G[y][x]if(x,y)in s else'.'for x in R(X))for y in R(Y))
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.