Залийте 2D сітку


9

Опис виклику

Назвемо двовимірний прямокутний масив (означає, що кожен його масив має однакову довжину), сітку . Кожна одиниця сітки - це порожній простір або межа . У сітці символів порожній простір представлений єдиним пробілом; будь-який інший персонаж трактується як кордон. Зразки сіток ( +'s, |' і та -додані для читабельності - вони не є частиною сітки ):

+----+
|    |
|    |
|    |
|    |
|    |
+----+  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.),

  • Куточок закритої ділянки не повинен бути Г-подібним. Наступні дві області є рівнозначними:

####         ##
#  #        #  #
#  #   ==   #  #
#  #        #  #
####         ##
  • Якщо одиниця під координатами є кордоном, ви можете залишити сітку незмінною (як у прикладі 4.) або розглянути її як порожній простір,

  • Ви можете обрати будь-який символ для заповнення / порожнього місця, якщо ви включите цю інформацію у подання,

  • Якщо ви використовуєте тип, який не charвідповідає вашим цілям, ви можете використовувати ints( 0для порожнього простору, 1для кордону) або booleans( trueі falseвідповідно) або будь-який інший тип - просто обов’язково включіть цю інформацію у ваше подання,

  • Координати, які використовуються у наведених вище прикладах, є 0-індексованими (row, column)координатами, оскільки це зручніше для двовимірного масиву. Якщо ви хочете використовувати (column, row)(декартову) систему та / або неіндексовані координати, вкажіть це у своєму поданні.

  • Якщо ви не знаєте, з чого почати, перегляньте статтю Вікіпедії про заливку

  • Пам'ятайте, що це a киньте виклик, тому зробіть свій код якомога коротшим!


Пов'язане: 1 , 2 , 3 , 4 , можливо більше.
Пітер Тейлор

Можливо, варто встановити тестовий випадок з однією одиницею кордону в положенні координат, щоб показати, що є два дійсних виходи: або сітка заповнена, або сітка є незмінною. (Якщо я правильно зрозумів вашу 3-
ту

Див. 4) оновлення
shooqie

1
Я не розумію, як ви отримуєте свій альтернативний приклад 4. Це, здається, руйнує осередкові осередки, окрім вказаного вхідного квадрата.
Джофан

Відповіді:


4

MATLAB, 30 7 байт

Оскільки ми можемо використовувати логічні введення замість рядків, ми можемо використовувати голою функцією, як це:

@imfill

Це анонімна функція. Для використання ми повинні припустити ім'я, наприклад f=@imfill. Тоді ми можемо просто оцінити його як f(input,point), де inputє логічна матриця, наприклад [0,0;0,1], і pointє 2d-вектором з 1-базисними координатами, наприклад [1,2].

Стара версія, що працює над рядками:

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

Ця анонімна функція приймає вхідний, а також векторний з координатами (індекс на основі 1). Функція imfillвиконує саме те, що нам потрібно, але працює лише на двійкових зображеннях. Ось чому ми перетворюємо вхідну матрицю в логічний масив (де #є межі, а (пробіли) - порожнеча), виконуємо заповнення і потім перетворюємо назад. (знову #заповнюється, простір не заповнюється).

Дякуємо @LuisMendo за - 1 байт.


Для строкової версії ви можете замінити ~=32її>32
Луїс Мендо

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, використовуючи !для символу заливки. Якщо стартове положення збігається з a #, не змінюється.

Зламатися:

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

Зауважте, що це покладається на зміну вхідного аргументу рядка, що заборонено, тому це може не працювати на всіх платформах (неявні декларації також роблять це нестандартним).


Ви можете зберегти 4 байта, змінюючи int w, l;просто w, l;- ПКУ по замовчуванням це intтип
Jacajack

@Jacajack хороший момент! Спасибі
Дейв

1

C - 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
Не забувайте, що ви можете зберегти крапки з комою, помістивши оператори всередину for( scanfтут), а використання першого параметра 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.