2Dグリッドを塗りつぶします


9

チャレンジの説明

グリッドを 2次元の長方形配列(すべてのサブ配列が同じ長さであることを意味します)と呼びましょう。グリッドのすべての単位は、空のスペースまたは境界線です。文字のグリッドでは、空のスペースは1つの空白で表されます。他の文字はすべてボーダーとして扱われます。サンプルグリッド(+さん、|さんと-読みやすさのために追加の- 彼らは、グリッドの一部ではありません):

+----+
|    |
|    |
|    |
|    |
|    |
+----+  an empty 4x5 grid

+------+
|      |
|  #   |
|  #   |
+------+  a 6x3 grid with 2 borders

+----------+
|          |
|          |
|  #####   |
|  #   #   |
| ##   # <------ enclosed area
| #    #   |
| ######   |
|          |
+----------+  a 10x8 grid with an enclosed area

2Dグリッドと1組の座標を指定して、座標で表される点を囲む囲まれた領域を塗りつぶします。

入力/出力のサンプル

1)

0 0
+----------+      +----------+
|          |      |XXXXXXXXXX|
|          |  ->  |XXXXXXXXXX|
|          |      |XXXXXXXXXX|
+----------+      +----------+

2)

6 5
+-----------------+      +-----------------+
|                 |      |                 |
|                 |      |                 |
|    ########     |      |    ########     |
|    #       #    |      |    #XXXXXXX#    |
|    #    ####    |      |    #XXXX####    |
|    #    #       |      |    #XXXX#       |
|    #    #       |  ->  |    #XXXX#       |
|    #    #       |      |    #XXXX#       |
|     ####        |      |     ####        |
|                 |      |                 |
|                 |      |                 |
+-----------------+      +-----------------+

3)

4 6
+-----------------+      +-----------------+
|                 |      |XXXXXXXXXXXXXXXXX|
|    ####         |      |XXXX####XXXXXXXXX|
|   #    #        |  ->  |XXX#    #XXXXXXXX|
|    ####         |      |XXXX####XXXXXXXXX|
|                 |      |XXXXXXXXXXXXXXXXX|
+-----------------+      +-----------------+

4)

4 5
+-----------------+      +-----------------+      +-----------------+ 
|                 |      |                 |      |                 |
|                 |      |                 |      |                 |
|    ####         |      |    ####         |      |     XXXX        |
|    ####         |  ->  |    ####         |  or  |     XXXX        |
|    ####         |      |    ####         |      |     XXXX        |
|                 |      |                 |      |                 |
+-----------------+      +-----------------+      +-----------------+

5)

2 6
+----------------+      +----------------+
|                |      |XXXXXXXXXXXXXXXX|
|                |      |XXXXXXXXXXXXXXXX|
|                |      |XXXXXXXXXXXXXXXX|
|                |  ->  |XXXXXXXXXXXXXXXX|
|                |      |XXXXXXXXXXXXXXXX|
|BBBBBBBBBBBBBBBB|      |BBBBBBBBBBBBBBBB|
|                |      |                |
|                |      |                |
+----------------+      +----------------+

ノート

  • 空のグリッドは囲まれていると見なされます。つまり、境界線もグリッドのエッジに沿って暗黙的に配置されます(例1および5を参照)。

  • 囲まれた領域のコーナーはL字型である必要はありません。したがって、次の2つの領域は同等です。

####         ##
#  #        #  #
#  #   ==   #  #
#  #        #  #
####         ##
  • 座標の下のユニットが境界線である場合は、グリッドを変更せずにそのままにするか(例4のように)、空のスペースとして扱います。

  • 送信にこの情報を含める限り、フィラー/空のスペースに任意の文字を選択できます。

  • char目的に適したタイプ以外のタイプを使用する場合は、ints0空のスペース、1境界線)またはbooleanstrueおよびfalseそれぞれ)またはその他のタイプを使用できます。提出物にこの情報を含めるようにしてください。

  • 上記の例で使用されている(row, column)座標は、2次元配列の方が便利なので、0インデックスの座標です。あなたが使用したい場合(column, row)(デカルト)システムおよび/または非0 -インデックス付きの座標を、あなたの提出でそれを指定します。

  • どこから始めればよいかわからない場合は、洪水補給に関するWikipediaの記事を確認してください。

  • これは課題であることを忘れないでください。コードをできるだけ短くしてください!


関連:1234、おそらくもっと。
Peter Taylor

2つの有効な出力があることを示すために、座標の位置に単一の境界単位を持つテストケースを用意する価値があるかもしれません。グリッドがすべて塗りつぶされているか、グリッドが変更されていないかのどちらかです。(私があなたの3番目のノートを正しく理解した場合。)
trichoplax

exを参照してください。4)更新
shooqie

1
別の例4を取得する方法がわかりません。これは、指定された入力正方形以外の境界セルを破壊しているようです。
Joffan

回答:


4

MATLAB、30 7バイト

文字列の代わりに論理入力を使用できるため、そのままの関数を使用できます。

@imfill

これは無名関数です。使用法については、名前を想定する必要がありf=@imfillます。以下のように、我々はそれを評価できるf(input,point)ところ、input例えば、論理的な行列であり[0,0;0,1]、そしてpoint例えば、1ベースの座標を持つ2次元ベクトルです[1,2]

文字列を処理する古いバージョン:

@(a,p)[imfill(a>32,p)*3+32,'']

この無名関数は、入力と、座標(1ベースのインデックス)を持つベクトルを受け入れます。この関数imfillは必要なことを正確に実行しますが、バイナリイメージでのみ機能します。そのため、入力行列を論理配列に変換し(場所#は境界であり、(スペース)はvoidです)、塗りつぶしを実行してから元に戻します。(再び#埋められ、スペースは埋められません)。

-おかげでため@LuisMendo 1バイト。


文字列バージョンについて、あなたは置き換えることができます~=32>32
ルイスMendo

3

C、162バイト

w,l;char*d;f(z){z<0||z>l||d[z]^32||++d[z]&&f(z+1)+f(z-1)+f(z+w)+f(z-w);}main(c,v)char**v;{l=strlen(d=v[3]),w=strchr(d,10)-d+1,f(atoi(v[2])*w+atoi(v[1]));puts(d);}

引数(./floodfill X Y grid)から入力を受け取ります。グリッドは各行を含む\n\r\n、その間になければなりません。最後の改行はオプションです。シェルから呼び出すことがわかった最も簡単な方法:

./floodfill 1 0 "$(printf "   \n###\n   \n")"
# or
./floodfill 1 0 "$(cat gridfile)"

!充填文字に使用して、stdoutに出力します。開始位置がと一致する場合、#変更は行われません。

壊す:

                                    // GCC is happy enough without any imports
w,l;                                // Globals (line width, total length)
char*d;                             // Global grid pointer
f(z){                               // "Fill" function - z=current cell
    z<0||z>l||                      // Check if out-of-bounds...
    d[z]^32||                       // ...or not empty
        ++d[z]&&                    // Fill cell...
        f(z+1)+f(z-1)+f(z+w)+f(z-w);// ...and continue in "+" pattern
}
main(c,v)char**v;{                  // K&R style function to save 2 bytes
    l=strlen(d=v[3]),               // Store grid & length
    w=strchr(d,10)-d+1,             // Store width of grid (including newlines)
    f(atoi(v[2])*w+atoi(v[1]));     // Parse X & Y arguments and invoke fill

    puts(d);}                       // Print the result

これは禁止されている入力引数文字列の変更に依存しているため、これはすべてのプラットフォームで機能するとは限らないことに注意してください(暗黙の宣言により、これは非標準になります)。


int w, l;単純に変更することで4バイトを節約できますw, l;int
-gccは

@Jacajack良い点!ありがとう
デイブ

1

C - 263の 247 240 238バイト

これは最初の 2番目、3番目のバージョンです。コードも縮小できると思います。

m[99][99],x,y,a,b,c,n;f(v,w){if(m[v][w]==32){m[v][w]=88;f(v,w+1);f(v+1,w);f(v,w-1);f(v-1,w);}}main(){scanf("%d %d\n",&a,&b);for(;~(c=getchar());m[x++][y]=c,n=x>n?x:n)c==10&&++y&&(x=0);f(b+2,a+1);for(a=-1;++a<y*n+n;)putchar(m[a%n][a/n]);}

そして読みやすいバージョン:

m[99][99], x, y, a, b, c, n;

/*
    a, b - flood fill start coordinates
    v, w - recursive function start coordinates
    x, y - iterators
    c - character read
    m - map
    n - maximum map width found

*/


//Recursive flood function
f( v, w )
{
    if ( m[v][w] == 32 ) //If field is empty (is ' '?)
    {
        m[v][w] = 88; //Put 'X' there
        f(v,w+1);f(v+1,w); //Call itself on neighbour fields
        f(v,w-1);f(v-1,w);
    }
}

main( )
{
    //Read coordinates
    scanf( "%d %d\n", &a, &b );

    //Read map (put character in map, track maximum width)
    for ( ; ~( c = getchar( ) ); m[x++][y] = c, n = x > n ? x : n )
        c == 10 && ++y && ( x = 0 );

    //Flood map
    f( b + 2, a + 1 );

    //Draw
    for ( a = -1; ++a < y * n + n; )
            putchar( m[a % n][a / n] );     

}

コンパイルして実行:
gcc -o flood floodgolf.c && cat 1.txt | ./flood

リソース:

注:私はint値に取り組んでいます。すべての(32)は空のスペースとして扱われます。他の値はすべてボーダーとして扱われます。座標はフォーマットです(row, column)


1
forscanfここ)内にステートメントを置くことでセミコロンを節約でき、安価なint宣言としてmainの最初のパラメーターを使用すると、ほとんどのコンパイラーで機能することを忘れないでください。また、配列をフラット化することで少し節約できるかもしれません(確かに印刷ループに役立つはずです)
Dave

@Daveそうです。このコードを書いて以来、少し学びました。データを1D配列で保存すると、多くの節約にもなりますが、明らかにあなたのアイデアをコピーしたくありません。後で何ができるか見てみます。ありがとう!
Jacajack

0

Python 2、158バイト

オンラインでお試しください。単純な再帰的ソリューション

a,X,Y=input()
M=len(a)
N=len(a[0])
def R(x,y):
 if~0<x<M and~0<y<N and a[x][y]:a[x][y]=0;R(x-1,y);R(x+1,y);R(x,y-1);R(x,y+1)
R(X,Y)
print'\n'.join(map(str,a))

行と列の順序で0インデックス

1-空のスペース、0-塗りつぶされたスペース

1と0の配列と2つの数値の配列として入力を受け取ります


0

Perl 5、129 + 1(-a)= 130バイト

sub f{my($r,$c)=@_;$a[$r][$c]eq$"&&($a[$r][$c]=X)&&map{f($r+$_,$c);f($r,$c+$_)}-1,1}@a=map[/./g],<>;f$F[0]+1,$F[1]+1;say@$_ for@a

オンラインでお試しください!

どうやって?

sub f{   # recursive subroutine
  my($r,$c)=@_; # taking row and column as inputs
  $a[$r][$c]eq$"&&  # using Boolean short circuit as an 'if' statement to 
                    # check if the current position in the global array is blank
  ($a[$r][$c]=X)&&  # then setting it to 'X'
  map{f($r+$_,$c);f($r,$c+$_)}-1,1 # and checking the four surrounding spaces
}
# -a command line option implicitly splits the first line into the @F array
@a=map[/./g],<>;    # put the input in a 2-D array
f$F[0]+1,$F[1]+1;   # start the fill at the given position, correcting for
                    # Perl's 0 based arrays
say@$_ for@a        # output the resulting pattern
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.