填充2D网格


9

挑战说明

让我们将其称为二维矩形数组(意味着其每个子数组具有相同的长度),即grid。网格的每个单元都是空白边框。在字符网格中,空白由单个空格表示;其他任何字符均视为边框。样本网格(为了便于阅读而添加了+,,|-它们不属于网格):

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

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

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

给定2D网格和一对坐标,请填充由坐标表示的点周围的封闭区域。

样本输入/输出

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形。因此,以下两个区域是等效的:

####         ##
#  #        #  #
#  #   ==   #  #
#  #        #  #
####         ##
  • 如果坐标下的单位恰好是边界,则可以使网格保持不变(如示例4所示),也可以将其视为空白空间,

  • 您可以选择任何字符作为填充符/空白,只要您在提交中包含此信息,

  • 如果使用比其他类型char适合你的目的更好,你可以使用ints0空的空间,1为边界)或booleanstruefalse分别)或任何其他类型的-只要确保在您提交这些信息,

  • 上面的示例中使用的(row, column)坐标是0索引坐标,因为它对于二维数组更方便。如果要使用(column, row)(笛卡尔)系统和/或非零索引坐标,请在提交中指定。

  • 如果您不知道从哪里开始,请查看Wikipedia中有关洪水填充的文章

  • 请记住,这是一个 挑战,所以让您的代码越短越好!


相关:1234,可能更多。
彼得·泰勒

在坐标位置使用一个带有单个边框单位的测试用例可能值得一看,以表明有两个有效的输出:要么网格已全部填充,要么网格未更改。(如果我正确理解了您的第三个音符。)
trichoplax

见前。4)更新
shooqie

1
我不知道如何得到替代示例4。这似乎是在破坏指定输入正方形以外的边界单元。
乔芬2013年

Answers:


4

MATLAB,30 7字节

由于我们可以使用逻辑输入而不是字符串,因此可以使用裸函数,如下所示:

@imfill

这是一个匿名函数。对于用法,我们必须假设一个名称,例如f=@imfill。然后,我们可以将其评估为f(input,point),其中input是逻辑矩阵,例如[0,0;0,1]point是具有基于1坐标的2d矢量,例如[1,2]

在字符串上运行的旧版本:

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

此匿名函数接受输入以及带有坐标(从1开始的索引)的向量。该功能imfill完全可以满足我们的需求,但是仅对二进制图像起作用。这就是为什么我们将输入矩阵转换为逻辑数组(其中#边界是(空间)是空),然后执行填充并随后转换回去的原因。(再次#填充,空间未填充)。

感谢@LuisMendo提供-1个字节。


对于字符串版本,您可以替换~=32>32
Luis Mendo,2016年

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在每行之间,最后的换行符是可选的。我发现从shell调用的最简单方法是:

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

输出到标准输出,!用于填充字符。如果开始位置与一致#,则不进行更改。

分解:

                                    // 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;-gcc默认将其int键入
-Jacajack

@jacajack好点!谢谢
戴夫

1

Ç - 263 247 240 238个字节

这是第一 第二第三版本,我相信代码也可以缩小。

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这里)内放置语句来保存分号,并且将main的第一个参数用作便宜的int声明在大多数编译器中都可以使用。另外,您也可以通过展平阵列来节省一点时间(当然应该有助于打印循环)
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以及两个数字的数组的数组


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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.