Riempi una griglia 2D


9

Descrizione della sfida

Chiamiamo un array rettangolare bidimensionale (il che significa che ogni subarray ha la stessa lunghezza), una griglia . Ogni unità di una griglia è uno spazio vuoto o un bordo . In una griglia di caratteri, lo spazio vuoto è rappresentato da un singolo spazio bianco; qualsiasi altro personaggio viene trattato come un bordo. Griglie di esempio ( +", |" e -"aggiunte" per la leggibilità - non fanno parte della griglia ):

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

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

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

Data una griglia 2D e una coppia di coordinate, riempire l'area chiusa che circonda il punto rappresentato dalle coordinate.

Ingressi / uscite di esempio

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

Appunti

  • Una griglia vuota è considerata chiusa, vale a dire che i bordi si trovano implicitamente anche lungo i bordi della griglia (vedere gli esempi 1. e 5.),

  • Un angolo di un'area chiusa non deve essere a forma di L. Le seguenti due aree sono pertanto equivalenti:

####         ##
#  #        #  #
#  #   ==   #  #
#  #        #  #
####         ##
  • Se un'unità sotto le coordinate sembra essere un bordo, puoi lasciare la griglia invariata (come nell'esempio 4.) o trattarla come uno spazio vuoto,

  • Puoi scegliere qualsiasi carattere per riempimento / spazio vuoto purché includi queste informazioni nella presentazione,

  • Se usi un tipo diverso da quello charadatto ai tuoi scopi, puoi usare ints( 0per spazio vuoto, 1per bordo) o booleans( truee falserispettivamente) o qualsiasi altro tipo - assicurati di includere queste informazioni nel tuo invio,

  • Le coordinate utilizzate negli esempi precedenti sono (row, column)coordinate con indice 0 , poiché è più conveniente per un array bidimensionale. Se si desidera utilizzare il (column, row)sistema (cartesiano) e / o coordinate non indicizzate 0, specificarlo nella richiesta.

  • Se non sai da dove cominciare, consulta l' articolo di Wikipedia sul riempimento di inondazioni

  • Ricorda che si tratta di una sfida con il , quindi rendi il tuo codice il più breve possibile!


Correlati: 1 , 2 , 3 , 4 , forse di più.
Peter Taylor,

Potrebbe valere la pena avere un caso di test con una singola unità di confine nella posizione delle coordinate, per mostrare che ci sono due output validi: O la griglia è tutta piena o la griglia è invariata. (Se ho capito bene la tua terza nota.)
trichoplax,

Vedi ex. 4) aggiornamento
shooqie

1
Non capisco come si ottiene l'esempio alternativo 4. Sembra che stia distruggendo le celle di confine diverse dal quadrato di input specificato.
Joffan,

Risposte:


4

MATLAB, 30 7 byte

Poiché possiamo usare input logici anziché stringhe, possiamo usare la funzione bare, in quanto è:

@imfill

Questa è una funzione anonima. Per l'utilizzo, dobbiamo assumere un nome, ad es f=@imfill. Quindi possiamo semplicemente valutarlo come f(input,point), dove inputè una matrice logica, ad esempio [0,0;0,1], ed pointè un vettore 2D con coordinate basate su 1, ad esempio [1,2].

Vecchia versione che funziona su stringhe:

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

Questa funzione anonima accetta l'input e un vettore con le coordinate (indice basato su 1). La funzione imfillfa esattamente ciò di cui abbiamo bisogno, ma opera solo su immagini binarie. Questo è il motivo per cui convertiamo la matrice di input in una matrice logica (dove #sono i confini e (spazi) sono il vuoto), eseguiamo il riempimento e quindi riconvertiamo. (di nuovo #è pieno, lo spazio non è pieno).

Grazie @LuisMendo per - 1 byte.


Per la versione stringa, puoi sostituirla ~=32con>32
Luis Mendo il

3

C, 162 byte

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

Prende input dagli argomenti ( ./floodfill X Y grid). La griglia deve contenere \no \r\ntra ciascuna riga, la nuova riga finale è facoltativa. Il modo più semplice che ho trovato per invocare dalla shell:

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

Emette su stdout, usando !per il carattere di riempimento. Se la posizione iniziale coincide con a #, non cambia.

Abbattersi:

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

Si noti che ciò si basa sulla modifica della stringa dell'argomento di input, che è vietata, quindi potrebbe non funzionare su tutte le piattaforme (anche le dichiarazioni implicite rendono questo non standard).


Puoi salvare 4 byte cambiando int w, l;semplicemente in w, l;- gcc il default lo intdigita
Jacajack il

@Jacajack buon punto! Grazie
Dave,

1

C - 263 247 240 238 byte

Questa è la prima seconda terza versione, credo che anche il codice possa essere ridotto.

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

E versione leggibile:

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

}

Compila ed esegui:
gcc -o flood floodgolf.c && cat 1.txt | ./flood

risorse:

Nota: sto lavorando su intvalori. Ogni (32) viene trattato come spazio vuoto. Qualsiasi altro valore viene trattato come bordo. Le coordinate sono in formato(row, column)


1
Non dimenticare che puoi salvare i punti e virgola inserendo le istruzioni all'interno di for( scanfqui) e utilizzando il primo parametro di main come dichiarazione int economica funzionerà nella maggior parte dei compilatori. Inoltre potresti essere in grado di risparmiare un po 'appiattendo l'array (dovrebbe sicuramente aiutare il ciclo di stampa)
Dave,

@Dave Esatto. Ho imparato un po 'da quando ho scritto questo codice. Penso che l'archiviazione dei dati nell'array 1D mi aiuterebbe a risparmiare molto, ma ovviamente non voglio copiare la tua idea. Vedrò cosa posso fare più tardi. Grazie!
Jacajack,

0

Python 2, 158 byte

Provalo online . Semplice soluzione ricorsiva

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 indicizzato in ordine di colonna-riga

1 - spazio vuoto, 0 - spazio riempito

Accetta input come array di array di 1 e 0 e due numeri


0

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

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

Provalo online!

Come?

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.