Poli Nemo'yu bulmak!


11

Oh hayır! Nemo, küçük palyaço balığımız bu ASCII okyanusunda kayboluyor ve babası Marlin onu bulmaya çalışıyor.

Göreviniz Marlin'i Nemo'ya güvenle götürmek. Ama dikkat edin, gevşek bir beslenme çılgınlığı Bruce var, bu yüzden onu pahasına önlemek daha iyi!

ayrıntılar

Yalnızca küçük harfli alfabe içeren dikdörtgen ASCII okyanus ızgarası verilir a-z. Bu okyanus olacak nemo, marlinve bruceonun içinde sürekli bir Polyomino şeklinde, her zaman Polyomino ilk sütununda en üst hücreden başlayarak. Örneğin, olası tüm tetrominolardan geçerli olanlar aşağıdaki snippet'te listelenir

Ancak bunlar gibi formlar geçersizdir ve girdide bulunmayacaktır:

omen

ne
mo

nem
o

o
m
en

nem
 o

n
eo
m

Son olarak, göreviniz, yolunuzdaki herhangi bir hücrenin polyomino döşemesine bitişik olmadığından emin olarak polyomino döşemesinden marlinpolyomino döşemesine bir yol bulmaktır . Çıktınız, döşemenin, döşemenin ve bunları birleştiren yolun parçası olmayan tüm alfabe harflerini , küçük harf dışında yazdırılabilir ASCII aralığındaki (boşluk dahil) bir karakterle değiştirmelidir .nemobrucemarlinnemoa-z

Misal

Giriş okyanusu aşağıdaki gibi ise:

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

(3 polyomino şu şekilde:

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

)

O zaman geçerli bir çözüm şöyle görünebilir:

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

Snippet'in altında birkaç örnek daha bulunmaktadır:

notlar

  • Izgara her zaman mükemmel bir dikdörtgen olacak ve yalnızca bir polyomino karo içerir nemo, marlinve bruce.
  • Yolunuz bruceveya brucedöşemedeki herhangi bir hücrenin 4 bitişik (yukarı, aşağı, sol ve sağ) hücresinden geçmemelidir .
  • - arasında en az bir geçerli yol olacağı her zaman garanti marlinedilir nemo.
  • Burada en kısa yol gerekmemektedir, bu yüzden çıldırmak!
  • En kısa yolu bulmak zorunda olmasanız da, yoldaki herhangi bir hücre (marlin veya nemo içermeyen yol) yoldaki diğer ikiden fazla hücreye bitişik olamaz.
  • Yol marlinveya nemofayanslardan geçmemelidir , çünkü daha sonra küçük balıkları bir yön seçerken karıştırır.
  • Her zaman olduğu gibi, STDIN (veya en yakın eşdeğeri), komut satırı bağımsız değişkeni veya işlev parametresi aracılığıyla girdi alarak ve STDOUT (veya en yakın eşdeğeri), dönüş değeri veya işlev (çıkış) parametresi aracılığıyla çıktı üreterek bir program veya işlev yazabilirsiniz.
  • Çok satırlı giriş mümkün değilse, ızgaranın |yerine karakterle birleştirildiğini varsayabilirsiniz \n. Ayrıca girdiyi bir dizi ızgara satırı olarak da alabilirsiniz.

Bu kod golf yani bayt en kısa giriş kazanır.


Yol marlin (veya nemo) içinden geçebilir mi? yukarıdaki marlin kyukarıdaki lgörünür ise yukarıdaki çözüm hala geçerli olur mu? (
marlin'deki n'den nemo'ya

@KSab o zaman marlin karıştırır gibi hayır diyebilirim :)
Optimizer

Yanıtlar:


4

Matlab 560

Gereksiz tüm alanları, tüm noktalı virgülleri ve tüm yorumları kaldırırken 560 bayt. Çok daha fazla golf olabilir ama ben şu anda yorgun (belki yarın ...) Herkese iyi geceler.

Not: Yolun 4 mahalle ('+') bağlantılı olması gerektiğini varsaydım.

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

Arama fonksiyonu: (yeni hat gerekli değildir)

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

Çıktı:

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

Nasıl çalışır

İsimler çıkarılıyor

İlk bölüm, nemoişlev tarafından yapılan isimleri çıkarmaktır q(). İşlev önce her şeyi 0 olarak işaretler, daha sonra adın ilk harfini 1, daha sonra komşulukta 2sanki ikinci harf 1, sonra üçüncü vb. Bundan sonra nemosadece bir tane olması gerekir 4. Bundan 1sonra , tekrar bulana ve daha büyük olan diğer tüm sayıları silene kadar geriye doğru gideriz , böylece harflerin nemomaskelenmiş olduğu güzel bir maskeyi geri alırız . Bunu üç isim için de yapıyoruz ve daha sonra bir yol bulmaya devam edebiliriz.

Yolu bulma

Marlins pozisyonlarından başlıyoruz ve adım adım 'görüntü' deliğinden bir şok dalgası gönderiyoruz. Her adımda mesafe sayacını arttırır ve wavefront altındaki 'pikselleri' geçerli mesafe ile işaretleriz. (Genellikle en kısa yol algoritmalarıyla yapıldığından.) Bu dalga cephesi açıkça Bruce bölgesi tarafından engellenir, bu yüzden onun etrafında akacaktır. Bu adım, bir üst sınıra ulaşılana kadar tekrarlanır. Bu (kuşkusuz çok gevşek) üst sınır şimdi 'görüntünün' çevresidir (en kısa yollar her durumda çok daha kısa olacaktır). Test durumunda şöyle görünür:

 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

Şimdi nemopiksellerden başlayın ve her adımda mesafe sayacını azaltın ve yolumuza bir sonraki daha düşük mesafeye sahip bir komşu ekleyin (daha önce hesapladığımız mesafe haritasına göre).


3

Python 2-658

Hem zaman hem de bellekte çok çok verimsiz. Örüntüleri tanımlama işlevi özyinelemeli işlev S'dir ve yolları bulma işlevi temelde korkunç derecede verimsiz bir A * uygulaması olan C'dir.

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))

Test için bu (çok az) daha az golf olanı kullanın (her kiremit için yolu bir kez hesaplar)

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))
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.