Poly Nemoを見つける!


11

大野!ニモ、私たちの小さなカクレクマノミはこのASCIIの海で失われ、彼の父マーリンは彼を見つけようとしています。

あなたの仕事は、Marlinを安全にNemoに連れて行くことです。しかし、気をつけてください、私たちはルーズにブルースを食べているので、彼を避けてください!

詳細

小文字のアルファベットのみを含む長方形のASCIIオーシャングリッドが表示されますa-z。この海にはがありnemo、marlinそのbruce内部には連続ポリオミノの形で、常にポリオミノの最初の列の一番上のセルから始まります。たとえば、可能なすべてのテトロミノのうち、有効なものは以下のスニペットにリストされています

ただし、次のようなフォームは無効であり、入力には含まれません。

omen

ne
mo

nem
o

o
m
en

nem
 o

n
eo
m

最後に、marlinポリオミノタイルからポリオミノタイルへのパスを見つけて、パスnemo内のセルがbruceポリオミノタイルに隣接していないことを確認します。出力は、marlinタイル、nemoタイル、およびそれらの両方を接続するパスの一部ではないすべてのアルファベットを、小文字以外の印刷可能なASCII範囲(スペースを含む)の文字で置き換える必要がありa-zます。

例

入力海洋が次の場合:

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

(3つのpolyominosは次のとおりです。

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

)

有効なソリューションは次のようになります。

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

以下のスニペットには、さらにいくつかの例が含まれています。

ノート

  • グリッドは、常に完璧な長方形になるとの唯一のポリオミノのタイルが含まれていますnemo、marlinとbruce。
  • パスはbruce、bruceタイル内のセルの隣接する4つのセル(上、下、左、右)を通過してはなりません。
  • からmarlinまでの有効なパスが少なくとも1つあることが常に保証されnemoます。
  • ここには最短経路の要件はありませんので、気をつけてください!
  • 最短のパスを見つける必要はありませんが、パス内のセル(marlinまたはnemoを含まないパス)は、パス内の他の3つ以上のセルに隣接できません。
  • パスが通過するべきではないmarlinか、nemoそれがその後の方向を選ぶ際に小さな魚を混乱させるとして、タイル。
  • いつものように、STDIN(または最も近い同等物)、コマンドライン引数または関数パラメーターを介して入力を受け取り、STDOUT(または最も近い同等物)、戻り値または関数(出力)パラメーターを介して出力を生成するプログラムまたは関数を作成できます。
  • 複数行の入力が不可能な場合、グリッドはの|代わりに文字で結合されていると想定できます\n。入力をグリッド行の配列として取得することもできます。

これはコードゴルフであるため、バイト単位の最短エントリが優先されます。


パスはマーリン(またはニモ)を通過できますか?k上記のlマーリンが見える場合、上記のソリューションはまだ有効ですか?(マーリンのnからnemoへのパスを作成)
— KSab

@KSabそれはマーリンを混乱させるので、ノーと言うでしょう:)
— オプティマイザー

回答:


4

Matlab 560

不要なスペース、セミコロン、コメントをすべて削除すると560バイト。もっとゴルフができるかもしれませんが、今は疲れています(おそらく明日...)おやすみなさい。

PS:パスには4近傍( '+')接続性が必要だと思いました。

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

関数の呼び出し:(改行は不要です)

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

出力:

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

使い方

名前の抽出

最初の部分は名前を抽出しています、例えばnemo、それは機能によってされますq()。この関数は最初にすべてを0としてマークし1、次に名前の最初の文字をとしてマークし、次に2番目の文字を近所に2あるかのようにマークし、次に3番目の文字をマークします1。その後はnemo1つだけの場合があります4。それから、1再び見つかるまで逆方向に進み、それよりも大きい他のすべての数字を削除して、文字nemoがマスクされている素敵なマスクを取得します。3つの名前すべてに対してこれを行い、パスの検索に進むことができます。

パスを見つける

私たちはマーリンズのポジションから始めて、ホールの「イメージ」を通して衝撃波を段階的に送ります。各ステップで、距離カウンターを増やし、現在の距離で波面の下の「ピクセル」をマークします。(通常、最短経路アルゴリズムで行われます。)この波面は明らかにブルースの領域によってブロックされるため、彼の周りを流れます。このステップは、上限に達するまで繰り返されます。この(明らかに非常に緩やかな)上限は、「画像」の円周になります(いずれの場合も最短経路はずっと短くなります)。テストケースでは、次のようになります。

 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

ここで、nemoピクセルから開始し、各ステップで距離カウンターを減らして、パスに次の距離の小さい隣を追加します(以前に計算した距離マップに従って)。


3

Python 2-658

時間とメモリの両方で非常に非効率的です。パターンを識別する関数は再帰関数Sであり、パスを見つける関数はCです。これは基本的にひどく非効率的なA *実装です。

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

テストには、これを(非常にわずかに)少なく使用します(タイルごとに代わりにパスを1回計算します)。

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))
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.