2B ızgarayı seli doldurun


9

Meydan okuma açıklaması

İki boyutlu, dikdörtgen bir dizi (her alt dizisinin aynı uzunlukta olduğu anlamına gelir), bir ızgara diyelim . Bir ızgaranın her birimi boş bir alan veya kenarlıktır . Bir karakter ızgarasında, boş alan tek bir boşlukla temsil edilir; başka herhangi bir karakter kenarlık olarak kabul edilir. Örnek ızgaralar ( +', |' ve -'okunabilirlik için eklenmiştir - bunlar ızgaranın bir parçası değildir ):

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

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

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

2B ızgara ve bir çift koordinat verildiğinde, koordinatları temsil eden noktayı çevreleyen kapalı alanı doldurun.

Örnek girişler / çıkışlar

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

notlar

  • Boş bir ızgara kapalı olarak kabul edilir, yani sınırlar ızgaranın kenarları boyunca da dolaylı olarak yerleştirilir (bakınız örnek 1. ve 5.),

  • Kapalı bir alanın köşesinin L şeklinde olması gerekmez. Bu nedenle aşağıdaki iki alan eşdeğerdir:

####         ##
#  #        #  #
#  #   ==   #  #
#  #        #  #
####         ##
  • Koordinatların altındaki bir birim bir kenarlık olursa, ızgarayı değiştirmeden bırakabilirsiniz (örnek 4'teki gibi) veya boş bir alan olarak değerlendirebilirsiniz,

  • Bu bilgiyi gönderiye eklediğiniz sürece dolgu / boş alan için herhangi bir karakter seçebilirsiniz,

  • charAmaçlarınıza daha uygun bir tür kullanıyorsanız , ints( 0boş alan, 1kenarlık için) veya booleans( trueve falsesırasıyla) veya başka bir tür kullanabilirsiniz - bu bilgileri gönderiminize eklediğinizden emin olun,

  • Yukarıdaki örneklerde kullanılan (row, column)koordinatlar, iki boyutlu dizi için daha uygun olduğu için 0 dizinli koordinatlardır. (column, row)(Kartezyen) sistemi ve / veya 0 ile indekslenmemiş koordinatları kullanmak istiyorsanız , onu gönderiminizde belirtin.

  • Nereden başlayacağınızı bilmiyorsanız , taşkın dolgu hakkındaki Wikipedia makalesine göz atın

  • Bunun bir meydan okuma, bu yüzden kodunuzu mümkün olduğunca kısa yapın!


İlgili: 1 , 2 , 3 , 4 , muhtemelen daha fazlası.
Peter Taylor

İki geçerli çıktı olduğunu göstermek için, koordinatların bulunduğu konumda tek bir kenarlık birimi bulunan bir test senaryosuna sahip olabilirsiniz: Izgara tamamen doldurulur veya ızgara değişmez. (Ben doğru 3 notu anlamış demektir.)
placozoa

Bkz. Ör. 4) güncelleme
shooqie

1
Alternatif örnek 4'ü nasıl elde ettiğinizi anlamıyorum. Belirtilen girdi karesi dışındaki sınır hücrelerini yok ediyor gibi görünüyor.
Joffan

Yanıtlar:


4

MATLAB, 30 7 bayt

Dizeler yerine mantıksal girdileri kullanabileceğimiz için çıplak işlevi şu şekilde kullanabiliriz:

@imfill

Bu anonim bir işlevdir. Kullanım için bir ad varsaymalıyız, örn f=@imfill. Daha sonra bunu, mantıksal bir matrisin f(input,point)nerede inputolduğu [0,0;0,1]ve örneğin point1 tabanlı koordinatlara sahip bir 2d-vektörü olarak değerlendirebiliriz [1,2].

Dizelerde çalışan eski sürüm:

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

Bu anonim işlev, girişi ve koordinatları olan bir vektörü (1 tabanlı dizin) kabul eder. İşlev imfilltam olarak ihtiyacımız olanı yapar, ancak yalnızca ikili görüntülerde çalışır. Bu nedenle giriş matrisini mantıksal bir diziye dönüştürüyoruz ( #sınırlar nerede ve (boşluklar) boşluktur), dolguyu gerçekleştirir ve daha sonra geri dönüştürülür. (tekrar #doldurulur, boşluk doldurulmaz).

@LuisMendo için teşekkürler - 1 bayt .


Dize sürümünde, yerine ~=32göre>32
Luis Mendo

3

C, 162 bayt

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

Bağımsız değişkenlerden ( ./floodfill X Y grid) girdi alır . Izgara her satırı içermeli \nveya \r\narasında olmalıdır , son satırsonu isteğe bağlıdır. Kabuktan çağırmak için bulduğum en basit yol:

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

!Dolgu karakteri için stdout'a çıktılar . Başlangıç ​​konumu a ile çakışırsa #, değişiklik yapmaz.

Yıkmak:

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

Bunun, yasaklanmış olan giriş argümanı dizesini değiştirmeye bağlı olduğunu unutmayın, bu nedenle bu tüm platformlarda çalışmayabilir (örtülü bildirimler de bunu standart dışı yapar).


int w, l;Basitçe değiştirerek 4 bayt kaydedebilirsiniz w, l;- gcc varsayılan olarak intyazın
Jacajack

@Jacajack iyi bir nokta! Teşekkürler
Dave

1

C - 263 247 240 238 bayt

Bu birinci ikinci üçüncü versiyon, kod da daraltılabilir inanıyorum.

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]);}

Ve okunabilir versiyon:

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

}

Derleyin ve çalıştırın:
gcc -o flood floodgolf.c && cat 1.txt | ./flood

Kaynaklar:

Not: intDeğerler üzerinde çalışıyorum . Her (32) boş alan olarak kabul edilir. Başka herhangi bir değer kenarlık olarak kabul edilir. Koordinatlar biçimdedir(row, column)


1
for( scanfBurada) içine ifadeler koyarak noktalı virgül kaydedebileceğinizi unutmayın ve main'un ilk parametresini ucuz bir int bildirimi olarak kullanmak çoğu derleyicide çalışacaktır. Ayrıca dizinizi düzleştirerek biraz tasarruf edebilirsiniz (kesinlikle baskı döngüsüne yardımcı olmalıdır)
Dave

@Dave Bu doğru. Bu kodu yazdığımdan beri biraz öğrendim. 1D dizisinde veri depolamak da çok tasarruf etmeme yardımcı olacağını düşünüyorum, ama açıkçası fikrinizi kopyalamak istemiyorum. Sonra ne yapabileceğimi göreceğim. Teşekkürler!
Jacajack

0

Python 2, 158 bayt

Çevrimiçi deneyin . Basit özyinelemeli çözüm

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

Satır-sütun düzeninde 0 dizinli

1 - boş alan, 0 - dolu alan

Girdiyi 1 ve 0 dizileri dizisi ve iki sayı olarak alır


0

Perl 5 , 129 + 1 (-a) = 130 bayt

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

Çevrimiçi deneyin!

Nasıl?

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