Vérifiez si tous les éléments non nuls d'une matrice sont connectés

19

Contribution:

Une matrice contenant des entiers dans l'intervalle [0 - 9] .

Défi:

Déterminez si tous les éléments non nuls sont connectés les uns aux autres verticalement et / ou horizontalement.

Production:

Une valeur vraie si tous sont connectés et une valeur fausse s'il y a des éléments / groupes non nuls qui ne sont pas connectés à d'autres éléments / groupes.

Cas de test:

Les cas de test sont séparés par une ligne. Les cas de test peuvent être trouvés dans des formats plus pratiques ici ( bravo à Dada ).

Les éléments suivants sont tous connectés et doivent renvoyer une valeur véridique:

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

Les éléments suivants ne sont pas tous connectés et doivent renvoyer une valeur fausse:

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

Il s'agit de , donc la soumission la plus courte dans chaque langue l'emporte. Les explications sont encouragées!


Inspiré par ce défi .

Stewie Griffin
la source
Peut-être que l'entrée ne doit contenir que des uns et des zéros (ou des vérités et des fausses), car il s'agit essentiellement de composants connectés.
NikoNyrh
Pouvons-nous prendre l'entrée comme un tableau 1d et un certain nombre de colonnes?
ovs
@ovs sûr. Je ne vois pas que cela devrait vous donner des avantages sur les autres personnes qui ont déjà répondu.
Stewie Griffin
2
Connexes : combien de zéros avez-vous besoin de changement pour faire tous les éléments connectés nonzéro
dylnan
Connexes : comptez le nombre de composants (mais avec des entrées diagonales adjacentes).
Misha Lavrov

Réponses:

9

Retina 0.8.2 , 80 77 octets

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

Essayez-le en ligne! Edit: enregistré 1 octet grâce à @FryAmTheEggman. Explication:

T`d`@1

Simplifiez à un tableau de @s et 1s.

1`1
_

Remplacez-le 1par un _.

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

Flood remplissage du _au adjacents 1s.

^\D+$

Testez s'il en 1reste.

Neil
la source
@FryAmTheEggman Merci, et vous m'avez donné une idée de la façon d'économiser encore deux octets!
Neil
7

JavaScript (ES6), 136 135 octets

Renvoie un booléen.

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

Cas de test

Commenté

La fonction récursive g () recherche d'abord une cellule non nulle (tant que l'indicateur défini globalement z est défini sur 0 ) puis commence le remplissage à partir de là (dès que 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()
Arnauld
la source
7

MATL , 7 octets

4&1ZI2<

Cela donne une matrice contenant tous les uns comme sortie véridique , ou une matrice contenant au moins un zéro comme fausse . Essayez-le en ligne!

Vous pouvez également vérifier la véracité / fausseté en ajoutant un if-else branche au pied de page; essayez-le aussi!

Ou vérifiez tous les cas de test .

Explication

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
Luis Mendo
la source
1
Remarque de l'OP: en cas de doute: les sorties sont parfaitement fines et adhèrent au méta post lié.
Stewie Griffin
C'est époustouflant que MATL / matlab considère un tableau de nombres comme un IFF véridique, il ne contient pas de zéros. mathworks.com/help/matlab/ref/if.html (commentaire précédent supprimé)
Sparr
@Sparr (En fait, c'est ssi il ne contient pas de zéros et n'est pas vide .) J'ai également été confus quand j'ai appris que tout tableau non vide est véridique dans d'autres langues
Luis Mendo
4

C, 163 octets

Merci à @ user202729 pour avoir économisé deux octets!

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

Boucle dans la matrice jusqu'à ce qu'elle trouve le premier élément non nul. Arrête ensuite la boucle pendant un certain temps et remet récursivement à zéro chaque élément non nul connecté à l'élément trouvé. Parcourt ensuite le reste de la matrice en vérifiant si chaque élément est maintenant nul.

Essayez-le en ligne!

Déroulé:

*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;
}
Steadybox
la source
2

Perl, 80 79 78 73 70 octets

Comprend +2pour0a

Donnez la matrice d'entrée sans espaces sur STDIN (ou en fait sous forme de lignes séparées par tout type d'espaces)

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

Plus facile à lire si mis dans un fichier:

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

Java 8, 226 octets

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

Cela a pris un certain temps, donc je suis content que ça marche maintenant ..

Explication:

Essayez-le en ligne.

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)
Kevin Cruijssen
la source
1

Gelée , 23 octets

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

Essayez-le en ligne!


Explication.

Le programme étiquette chaque composant morphologique avec un nombre différent, puis vérifie s'il y a moins de 3 nombres. (y compris 0).

Considérez une ligne dans la 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]

Appliquer à plusieurs reprises cette fonction pour toutes les lignes et colonnes de la matrice, dans tous les ordres, éventuellement tous les composants morphologiques auront la même étiquette.

µ«Ḋ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.

Et enfin...

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.
user202729
la source
Bounty imaginaire si vous pouvez le faire en temps linéaire. Je pense que ce n'est pas possible dans Jelly, ¦prend même O (n).
user202729
(sans Python eval, bien sûr)
user202729
1

Haskell , 132 octets

 \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

extrait de Solve Hitori Puzzles

indices m répertorie les (line,cell) emplacements de la grille d'entrée.

filter((/=0).(m!)) filtre tous les emplacements avec des valeurs non nulles.

splitAt 1 partitionne le premier membre en une liste singleton à côté d'une liste de repos.

any(==1)[(b-d)^2+(p-q)^2|(d,q)<-f]dit si (b,p)touche la frontière f.

\(f,e)->partition(\(b,p)->touches(b,p)f)e sépare les touchers des pas [encore] touchers.

until(null.fst)advanceFrontier le répète jusqu'à ce que la frontière ne puisse plus avancer.

null.snd examine le résultat si tous les emplacements à atteindre ont bien été atteints.

Essayez-le en ligne!

Roman Czyborra
la source
1

Grime , 37 octets

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

Imprime 1pour correspondance et 0pour aucune correspondance. Essayez-le en ligne!

Explication

Le non terminal Ccorrespond à tout caractère différent de zéro qui est connecté au premier caractère différent de zéro de la matrice dans l'ordre de lecture anglais.

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.

Quelques explications: ecorrespond à un rectangle de largeur ou hauteur nulle qui fait partie du bord de la matrice d'entrée, et $est un "caractère générique" qui correspond à n'importe quoi. L'expression e/\0{/e\0*0$epeut être visualisée comme suit:

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

L'expression CoX^0oXest en fait analysée comme ((CoF)0)oX; les opérateurs oFet oXsont des suffixes et la concaténation des jetons signifie la concaténation horizontale. le^ juxtaposition donne alors une priorité plus élevée oX, donc la rotation est appliquée à la sous-expression entière. Le oFcorrige l'orientation de Caprès sa rotation de oX; sinon, il pourrait correspondre à la première coordonnée non nulle dans un ordre de lecture anglais tourné.

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

Cela signifie que tous les caractères non nuls doivent être connectés au premier. Le spécificateur de grille :est techniquement un opérateur de suffixe, maisC|:\0 est du sucre syntaxique pour (C|\0):.

Zgarb
la source
0

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

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

Essayez-le en ligne!

Xcali
la source
0

Python 2 , 211 163 150 octets

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

Essayez-le en ligne!

La sortie se fait via un code de sortie. L'entrée est une liste 1d et la largeur de la matrice.

ovs
la source