Controlla se tutti gli elementi diversi da zero in una matrice sono collegati


19

Ingresso:

Una matrice contenente numeri interi nell'intervallo [0 - 9] .

Sfida:

Determina se tutti gli elementi diversi da zero sono collegati tra loro in verticale e / o in orizzontale.

Produzione:

Un valore di verità se tutti sono collegati e un valore di falsa se ci sono elementi / gruppi diversi da zero che non sono collegati ad altri elementi / gruppi.

Casi test:

I casi di test sono separati da linea. I casi di test possono essere trovati in formati più convenienti qui (da Kudos a Dada ).

Di seguito sono tutti collegati e dovrebbe restituire un valore di verità:

0
--- 
0 0
---
1 1 1
0 0 0
---
1 0 0
1 1 1
0 0 1
---
0 0 0 0 0 0
0 0 3 5 1 0
0 1 0 2 0 1
1 1 0 3 1 6
7 2 0 0 3 0
0 8 2 6 2 9
0 0 0 0 0 5

Di seguito non sono tutti collegati e devono restituire un valore errato:

0 1
1 0
---
1 1 1 0
0 0 0 2
0 0 0 5
---
0 0 5 2
1 2 0 0
5 3 2 1
5 7 3 2
---
1 2 3 0 0 5
1 5 3 0 1 1
9 0 0 4 2 1
9 9 9 0 1 4
0 1 0 1 0 0

Si tratta di , quindi vince l'invio più breve in ogni lingua. Le spiegazioni sono incoraggiate!


Ispirato da questa sfida .


Forse l'input dovrebbe contenere solo uno e zeri (o verità e falsi), poiché si tratta essenzialmente di componenti collegati.
NikoNyrh,

Possiamo prendere l'input come un array 1d e un numero di colonne?
Ovs

@ovs sicuro. Non riesco a vedere che dovrebbe darti qualche vantaggio rispetto ad altre persone che hanno già risposto.
Stewie Griffin,

2
Correlati : quanti zeri è necessario modificare per connettere tutti gli elementi diversi da zero
dylnan

Correlati : conta il numero di componenti (ma con voci diagonali adiacenti).
Misha Lavrov,

Risposte:


9

Retina 0.8.2 , 80 77 byte

T`d`@1
1`1
_
+m`^((.)*)(1|_)( |.*¶(?<-2>.)*(?(2)(?!)))(?!\3)[1_]
$1_$4_
^\D+$

Provalo online! Modifica: salvato 1 byte grazie a @FryAmTheEggman. Spiegazione:

T`d`@1

Semplificare una matrice di @s e 1s.

1`1
_

Cambia uno 1in a _.

+m`^((.)*)(1|_)( |.*¶(?<-2>.)*(?(2)(?!)))(?!\3)[1_]
$1_$4_

Riempi inondazioni dalla a _alla 1s adiacente .

^\D+$

Verifica se sono 1rimaste.


@FryAmTheEggman Grazie e mi hai dato un'idea su come salvare anche altri due byte!
Neil,

7

JavaScript (ES6), 136 135 byte

Restituisce un valore booleano.

m=>!/[1-9]/.test((g=(y,x=0)=>1/(n=(m[y]||0)[x])&&!z|n?(m[y++][x]=0,z=n)?g(y,x)&g(--y-1,x)&g(y,x+1)||g(y,x-1):g(m[y]?y:+!++x,x):m)(z=0))

Casi test

Commentate

La funzione ricorsiva g () cerca prima una cella diversa da zero (fintanto che il flag z definito globalmente è impostato su 0 ) e quindi inizia il riempimento da lì (non appena z! = 0 ).

m =>                               // given the input matrix m
  !/[1-9]/.test((                  // test whether there's still a non-zero digit
    g = (y, x = 0) =>              //   after recursive calls to g(), starting at (x=0,y=0):
      1 / (n = (m[y] || 0)[x]) &&  //     n = current cell; if it is defined:
      !z | n ? (                   //       if z is zero or n is non-zero:
          m[y++][x] = 0,           //         we set the current cell to zero
          z = n                    //         we set z to the current cell
        ) ?                        //         if z is non-zero:
          g(y, x) &                //           flood-fill towards bottom
          g(--y - 1, x) &          //           flood-fill towards top
          g(y, x + 1) ||           //           flood-fill towards right
          g(y, x - 1)              //           flood-fill towards left
        :                          //         else:
          g(m[y] ? y : +!++x, x)   //           look for a non-zero cell to start from
      :                            //       else:
        m                          //         return the matrix
    )(z = 0)                       //   initial call to g() + initialization of z
  )                                // end of test()

7

MATL , 7 byte

4&1ZI2<

Questo dà una matrice che contiene tutti quelli come output di verità , o una matrice che contiene almeno uno zero come falsy . Provalo online!

È inoltre possibile verificare la verità / falsità aggiungendo un if- elseramo a piè di pagina; provalo anche tu!

Oppure verifica tutti i casi di test .

Spiegazione

4       % Push 4 (defines neighbourhood)
&       % Alternative input/output specification for next function
1ZI     % bwlabeln with 2 input arguments: first is a matrix (implicit input),
        % second is a number (4). Nonzeros in the matrix are interpreted as
        % "active" pixels. The function gives a matrix of the same size
        % containing positive integer labels for the connected components in 
        % the input, considering 4-connectedness
2<      % Is each entry less than 2? (That would mean there is only one
        % connected component). Implicit display

1
Nota di OP: in caso di dubbi: gli output sono perfettamente perfetti e aderiscono al meta post collegato.
Stewie Griffin,

Mi viene in mente che MATL / matlab considera una serie di numeri come IFF veritiera che non contiene zeri. mathworks.com/help/matlab/ref/if.html (commento precedente eliminato)
Sparr

@Sparr (In realtà, è iff non contiene zeri e non è vuoto .) Ero anche confuso quando ho saputo che qualsiasi array non vuoto è vero in altre lingue
Luis Mendo


4

C, 163 byte

Grazie a @ user202729 per aver salvato due byte!

*A,N,M;g(j){j>=0&j<N*M&&A[j]?A[j]=0,g(j+N),g(j%N?j-1:0),g(j-N),g(++j%N?j:0):0;}f(a,r,c)int*a;{A=a;N=c;M=r;for(c=r=a=0;c<N*M;A[c++]&&++r)A[c]&&!a++&&g(c);return!r;}

Passa attraverso la matrice fino a quando non trova il primo elemento diverso da zero. Quindi interrompe il ciclo per un po 'e imposta in modo ricorsivo su zero ogni elemento diverso da zero collegato all'elemento trovato. Quindi scorre il resto della matrice controllando se ogni elemento è zero.

Provalo online!

srotolato:

*A, N, M;

g(j)
{
    j>=0 & j<N*M && A[j] ? A[j]=0, g(j+N), g(j%N ? j-1 : 0), g(j-N), g(++j%N ? j : 0) : 0;
}

f(a, r, c) int*a;
{
    A = a;
    N = c;
    M = r;

    for (c=r=a=0; c<N*M; A[c++] && ++r)
        A[c] && !a++ && g(c);

    return !r;
}

2

Perl, 80 79 78 73 70 byte

Include +2per0a

Dare la matrice di input senza spazi su STDIN (o in effetti come righe separate da qualsiasi tipo di spazio)

perl -0aE 's%.%$".join"",map chop,@F%seg;s%\b}|/%z%;y%w-z,-9%v-~/%?redo:say!/}/'
000000
003510
010201
110316
720030
082629
000005
^D

Più facile da leggere se inserito in un file:

#!/usr/bin/perl -0a
use 5.10.0;
s%.%$".join"",map chop,@F%seg;s%\b}|/%z%;y%w-z,-9%v-~/%?redo:say!/}/

1

Java 8, 226 byte

m->{int c=0,i=m.length,j;for(;i-->0;)for(j=m[i].length;j-->0;)if(m[i][j]>0){c++;f(m,i,j);}return c<2;}void f(int[][]m,int x,int y){try{if(m[x][y]>0){m[x][y]=0;f(m,x+1,y);f(m,x,y+1);f(m,x-1,y);f(m,x,y-1);}}catch(Exception e){}}

Ci è voluto un po 'di tempo, quindi sono contento che funzioni ora ..

Spiegazione:

Provalo online.

m->{                   // Method with integer-matrix parameter and boolean return-type
  int c=0,             //  Amount of non-zero islands, starting at 0
      i=m.length,j;    //  Index integers
  for(;i-->0;)         //  Loop over the rows
    for(j=m[i].length;j-->0;)
                       //   Inner loop over the columns
      if(m[i][j]>0){   //    If the current cell is not 0:
        c++;           //     Increase the non-zero island counter by 1
        f(m,i,j);}     //     Separate method call to flood-fill the matrix
  return c<2;}         //  Return true if 0 or 1 islands are found, false otherwise

void f(int[][]m,int x,int y){
                        // Separated method with matrix and cell input and no return-type
  try{if(m[x][y]>0){    //  If the current cell is not 0:
    m[x][y]=0;          //   Set it to 0
    f(m,x+1,y);         //   Recursive call south
    f(m,x,y+1);         //   Recursive call east
    f(m,x-1,y);         //   Recursive call north
    f(m,x,y-1);}        //   Recursive call west
  }catch(Exception e){}}//  Catch and swallow any ArrayIndexOutOfBoundsExceptions
                        //  (shorter than manual if-checks)


1

Gelatina , 23 byte

FJṁa@µ«Ḋoµ€ZUµ4¡ÐLFQL<3

Provalo online!


Spiegazione.

Il programma etichetta ogni componente morfologico con un numero diverso, quindi controlla se ci sono meno di 3 numeri. (compreso 0).

Considera una riga nella matrice.

«Ḋo   Given [1,2,3,0,3,2,1], return [1,2,3,0,2,1,1].
«     Minimize this list (element-wise) and...
 Ḋ      its dequeue. (remove the first element)
      So min([1,2,3,0,3,2,1],
             [2,3,0,3,2,1]    (deque)
      ) =    [1,2,0,0,2,1,1].
  o   Logical or - if the current value is 0, get the value in the input.
         [1,2,0,0,2,1,1] (value)
      or [1,2,3,0,3,2,1] (input)
      =  [1,2,3,0,2,1,1]

Applicare ripetutamente questa funzione per tutte le righe e le colonne della matrice, in tutti gli ordini, alla fine tutti i componenti morfologici avranno la stessa etichetta.

µ«Ḋoµ€ZUµ4¡ÐL  Given a matrix with all distinct elements (except 0),
               label two nonzero numbers the same if and only if they are in
               the same morphological component.
µ«Ḋoµ          Apply the function above...
     €           for ach row in the matrix.

      Z        Zip, transpose the matrix.
       U       Upend, reverse all rows in the matrix.
               Together, ZU rotates the matrix 90° clockwise.
         4¡    Repeat 4 times. (after rotating 90° 4 times the matrix is in the
               original orientation)
           ÐL  Repeat until fixed.

E infine...

FJṁa@ ... FQL<3   Main link.
F                 Flatten.
 J                Indices. Get `[1,2,3,4,...]`
  ṁ               old (reshape) the array of indices to have the same
                  shape as the input.
   a@             Logical AND, with the order swapped. The zeroes in the input
                  mask out the array of indices.
      ...         Do whatever I described above.
          F       Flatten again.
           Q      uniQue the list.
            L     the list of unique elements have Length...
             <3   less than 3.

Taglie immaginarie se riesci a farlo in tempo lineare. Penso che non sia possibile in Jelly, ¦prende anche O (n).
user202729

(senza Python eval, ovviamente)
user202729

1

Haskell , 132 byte

 \m->null.snd.until(null.fst)(\(f,e)->partition(\(b,p)->any(==1)[(b-d)^2+(p-q)^2|(d,q)<-f])e).splitAt 1.filter((/=0).(m!)).indices$m

estratto da Solve Hitori Puzzles

indices melenca le (line,cell)posizioni della griglia di input.

filter((/=0).(m!)) filtra tutte le posizioni con valori diversi da zero.

splitAt 1 partiziona il primo membro in un elenco singleton accanto a un elenco di riposo.

any(==1)[(b-d)^2+(p-q)^2|(d,q)<-f]dice se (b,p)tocca la frontiera f.

\(f,e)->partition(\(b,p)->touches(b,p)f)e separa i toucher dai non [ancora] toucher.

until(null.fst)advanceFrontier lo ripete fino a quando la frontiera non può avanzare oltre.

null.snd esamina il risultato se tutte le località da raggiungere sono state effettivamente raggiunte.

Provalo online!


1

Grime , 37 byte

C=[,0]&<e/\0{/e\0*0$e|CoF^0oX
e`C|:\0

Stampa 1per corrispondenza e 0per nessuna corrispondenza. Provalo online!

Spiegazione

Il nonterminal Ccorrisponde a qualsiasi carattere diverso da zero collegato al primo carattere diverso da zero della matrice nell'ordine di lettura inglese.

C=[,0]&<e/\0{/e\0*0$e|CoF^0oX
C=                             A rectangle R matches C if
  [,0]                         it is a single character other than 0
      &                        and
       <                       it is contained in a rectangle S which matches this pattern:
        e/\0{/e\0*0$e           R is the first nonzero character in the matrix:
        e                        S has an edge of the matrix over its top row,
         /0{/                    below that a rectangle of 0s, below that
             e\0*0$e             a row containing an edge, then any number of 0s,
                                 then R (the unescaped 0), then anything, then an edge.
                    |CoF^0oX    or R is next to another match of C:
                     CoF         S is a match of C (with fixed orientation)
                        ^0       followed by R,
                          oX     possibly rotated by any multiple of 90 dergees.

Qualche spiegazione: ecorrisponde a un rettangolo di larghezza o altezza pari a zero che fa parte del bordo della matrice di input ed $è un "carattere jolly" che corrisponde a qualsiasi cosa. L'espressione e/\0{/e\0*0$epuò essere visualizzata come segue:

+-e-e-e-e-e-e-e-+
|               |
|      \0{      |
|               |
+-----+-+-------+
e \0* |0|   $   e
+-----+-+-------+

L'espressione CoX^0oXviene effettivamente analizzata come ((CoF)0)oX; gli oFe oXsono operatori postfix e la concatenazione di token significa concatenazione orizzontale. Il ^dà giustapposizione una precedenza maggiore poi oX, così la rotazione viene applicato all'intera sub-espressione. Il oFcorregge l'orientamento Cdopo che è ruotato di oX; altrimenti potrebbe corrispondere alla prima coordinata diversa da zero in un ordine di lettura inglese ruotato.

e`C|:\0
e`       Match entire input against pattern:
    :    a grid whose cells match
  C      C
   |     or
     \0  literal 0.

Ciò significa che tutti i caratteri diversi da zero devono essere collegati al primo. L'identificatore di griglia :è tecnicamente un operatore postfix, ma C|:\0è zucchero sintattico per (C|\0):.


0

Perl 5 , 131 129 + 2 ( -ap) = 133 byte

push@a,[@F,0]}{push@a,[(0)x@F];$\=1;map{//;for$j(0..$#F){$b+=$a[$'][$j+$_]+$a[$'+$_][$j]for-1,1;$\*=$b||!$a[$'][$j];$b=0}}0..@a-2

Provalo online!


0

Python 2 , 211 163 150 byte

m,w=input()
def f(i):a=m[i];m[i]=0;[f(x)for x in(i+1,i-1,i+w,i-w)if(x>=0==(i/w-x/w)*(i%w-x%w))*a*m[x:]]
f(m.index((filter(abs,m)or[0])[0]))<any(m)<1>q

Provalo online!

L'uscita è tramite il codice di uscita. L'input è un elenco 1d e la larghezza della matrice.

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.