Para encontrar islas de 1 y 0 en matriz

29

Dada una matriz bidimensional de 0 y 1s. Encuentre el número de islas para 1s y 0s donde los vecinos están solo en horizontal y vertical.

Given input:

1 1 1 0
1 1 1 0

output = 1 1
Number of 1s island = 1

xxx-
xxx-

Number of 0s island = 1 

---x
---x

------------------------------

Given input:

0 0 0 0
1 1 1 1
0 0 0 0
1 1 1 1

output = 2 2
Number of 1s island = 2

----
xxxx  <-- an island of 1s
----
xxxx  <-- another island of 1s

Number of 0s island = 2

xxxx  <-- an island
----
xxxx  <-- another island
----

------------------------------

Given input:

1 0 0
0 0 0
0 0 1
output = 2 1
Number for 1's island = 2:

x--  <-- an island of 1s
---
--x  <-- an island of 1s

Number of 0's island = 1:

-xx  \
xxx   > 1 big island of 0s
xx-  / 


------------------------------

Given input:

1 1 0
1 0 0
output = 1 1
Number for 1's island =1 and number of 0's island = 1

------------------------------

Given input:

1 1
1 1
output = 1 0
Number for 1's island =1 and number of 0's island = 0
KB alegría
fuente
11
Debe agregar un caso de prueba [[1,0];[0,1]]para asegurarse de que la conectividad diagonal no esté incluida
Sanchises
8
Yo te sugeriría que la salida puede estar en cualquier orden, siempre y cuando no se especifica el orden - que no añade ningún valor a la fuerza un orden
streetster
8
Bienvenido al sitio!
Arnauld
1
Lo que se respondió en los comentarios debe aclararse en el cuerpo del desafío. Y más específicamente, si realmente quiere que regresemos 1's antes de 0's, debe estar claramente establecido.
Arnauld
44
Caso de prueba sugerido: 11111 / 10001 / 10101 / 10001 / 111112 1
Kevin Cruijssen

Respuestas:

16

APL (Dyalog Unicode) , 29 28 bytes SBCS

-1 gracias a @ Adám

{≢∪∨.∧⍨⍣≡2>+/↑|∘.-⍨⍸⍵}¨⊂,~∘⊂

Pruébalo en línea!

⊂,~∘⊂ la matriz y su negación

{ para cada uno de ellos

⍸⍵ lista de pares de coordenadas de 1s

+/↑|∘.-⍨ matriz de distancias de manhattan

2> matriz vecina

∨.∧⍨⍣≡ clausura transitiva

≢∪ número de filas únicas

ngn
fuente
Esto es realmente inteligente. ¿Podría explicar por qué se garantiza que la línea final funcione? Es decir, por qué las filas únicas equivalen a la respuesta. Además, ¿el "cierre transitivo" es como el de J ^:_?
Jonás
1
@Jonah ver chat
ngn
16

J , 57 bytes

,&([:(0#@-.~~.@,)](*@[*[:>./((,-)#:i.3)|.!.0])^:_ i.@$)-.

Pruébalo en línea!

Esta es una de esas en las que la idea es increíblemente simple (y creo que es divertida), pero ejecutarla tenía cierta longitud mecánica que enmascara la simplicidad ... por ejemplo, cambiar la matriz original en todas las direcciones con un relleno 0 es lo más detallado ((,-)#:i.3) |.!.0.

Es probable que esta longitud mecánica se pueda jugar aún más, y puedo intentarlo mañana por la noche, pero ahora publicaré el quid de la cuestión.

Digamos que nuestra entrada es:

0 0 0 0
1 1 1 1
0 0 0 0
1 1 1 1

Comenzamos con una matriz de enteros únicos del mismo tamaño:

 0  1  2  3
 4  5  6  7
 8  9 10 11
12 13 14 15

Luego, para cada celda, encontramos el máximo de todos sus vecinos y lo multiplicamos por la máscara de entrada:

 0  0  0  0
 8  9 10 11
 0  0  0  0
13 14 15 15

Repetimos este proceso hasta que la matriz deja de cambiar:

 0  0  0  0
11 11 11 11
 0  0  0  0
15 15 15 15

Y luego cuente el número de elementos únicos que no son cero. Eso nos dice el número de islas 1.

Aplicamos el mismo proceso a "1 menos la entrada" para obtener el número de islas 0.

Jonás
fuente
3
Esto se parece mucho a un mecanismo de "relleno de inundación", realmente ordenado.
Matthieu M.
7

JavaScript (ES7),  138 ...  107106 bytes

Devuelve una matriz [ones, zeros].

f=(m,X,Y,V=.5,c=[0,0])=>m.map((r,y)=>r.map((v,x)=>V-v|(x-X)**2+(y-Y)**2>1||f(m,x,y,v,r[c[v^1]++,x]=2)))&&c

Pruébalo en línea!

¿Cómo?

Usamos una función recursiva. Durante la llamada inicial, buscamos 0 0 y 1 . Cada vez que encontramos ese punto de partida, incrementamos el contador de la isla correspondiente ( do[0 0] odo[1]2

Para guardar bytes, se usa exactamente el mismo código tanto para la iteración raíz como para las iteraciones recursivas, pero se comporta de manera un poco diferente.

Durante la primera iteración:

  • Comenzamos con V=0.5 0.5 para que V-v se redondea a 0 0 para ambos v=0 0v=1
  • XY(X-X)2+(y-Y)2(X,y)

Durante las iteraciones recursivas:

  • do2c[v ^ 1]++do

Comentado

f = (                 // f is a recursive function taking:
  m,                  //   m[]  = input binary matrix
  X, Y,               //   X, Y = coordinates of the previous cell, initially undefined
  V = .5,             //   V    = value of the previous cell, initially set to 0.5
                      //          so that the integer part of V - v is 0 for v = 0 or 1
  c = [0, 0]          //   c[]  = array of counters of 1's and 0's islands
) =>                  //          (or an integer when called recursively)
  m.map((r, y) =>     // for each row r[] at position y in m[]:
    r.map((v, x) =>   //   for each value v at position x in r[]:
      V - v |         //     abort if |V - v| ≥ 1
      (x - X) ** 2 +  //     or X and Y are defined and the quadrance between
      (y - Y) ** 2    //     (X, Y) and (x, y)
      > 1 ||          //     is greater than 1
      f(              //     otherwise, do a recursive call to f:
        m,            //       leave m[] unchanged
        x, y,         //       pass the new coordinates
        v,            //       pass the new reference value
        r[c[v ^ 1]++, //       increment c[v ^ 1] (ineffective if c is an integer)
          x           //       and set the current cell ...
        ] = 2         //       ... to 2
      )               //     end of recursive call
    )                 //   end of inner map()
  ) && c              // end of outer map(); return c
Arnauld
fuente
Este código no funciona para matrices grandes como 100 * 100, con solo 1 o 0 debido al desbordamiento de la pila.
KB alegría
3
@KBjoy A menos que se especifique explícitamente lo contrario en el desafío, nuestra regla predeterminada es que no nos importan los límites de implementación siempre que el algoritmo subyacente funcione en teoría para cualquier entrada. ( Aquí hay una meta publicación sobre eso, pero probablemente haya una más relevante en alguna parte.)
Arnauld
7

MATL , 14 12 bytes

,G@-K&1ZIugs

Pruébalo en línea! O verificar todos los casos de prueba .

Explicación

,        % Do twice
  G      %   Push input
  @      %   Push iteration index: first 0, then 1
  -      %   Subtract. This converts 0 and 1 into -1 and 0 in the second iteration 
  K      %   Push 4
  &1ZI   %   Label connected components of matrix using 4-connectedness. Zeros in the
         %   matrix are background. This replaces the nonzeros by 1, 2, 3, ..., where 
         %   each number defines a connected component
  u      %   Unique values. This gives [0; 1; 2; ..., L], where L is the number of
         %   connected components.
  g      %   Convert nonzeros to 1
  s      %   Sum. This gives L, to be output
         % End (implicit).
         % Display stack (implicit)
Luis Mendo
fuente
6

K (ngn / k) , 60 55 51 50 46 bytes

{#?{|/'x*\:x}/2>+/x*x:x-\:'x:(0,#*x)\&,/x}'~:\

Pruébalo en línea!

~:\ un par de la entrada y su negación (literalmente: negar iterar-converger)

{ }' para cada

,/x aplanar el argumento

&donde estan los 1s - lista de índices

(0,#*x)\ ancho de divmod (entrada) para obtener dos listas separadas para ys y xs

x-\:'x: distancias por eje ∆x y ∆y

x*x: cuadrarlos

+/ agregue ∆x² y ∆y²

2> matriz vecina

{|/'x*\:x}/ clausura transitiva

#? contar filas únicas

ngn
fuente
Después de ver tu respuesta, me alegro de no haber intentado abordar esta pregunta en K :)
streetter
2
@streetster jaja, gracias! ese no es el efecto que pretendía :) Me gustaría realmente como para animar a la gente a aprender (cualquier dialecto) k y golf en ella
NGN
6

Wolfram Language (Mathematica) , 64 62 bytes

Max@MorphologicalComponents[#,CornerNeighbors->1<0]&/@{#,1-#}&

Pruébalo en línea!

Gracias a attinat : podemos escribir en 1<0lugar de Falsey guardar dos bytes.

versión sin golf:

F[M_] := {Max[MorphologicalComponents[M,   CornerNeighbors -> False]], 
          Max[MorphologicalComponents[1-M, CornerNeighbors -> False]]}

Existe, por supuesto, un componente integrado de MathematicaMorphologicalComponents que toma una matriz (o una imagen) y devuelve lo mismo con los píxeles de cada isla conectada morfológicamente reemplazada por el índice de la isla. Tomar el Maxresultado de este da el número de islas (los ceros de fondo se dejan en cero, y el índice de la isla comienza en 1). Necesitamos hacer esto por separado para la matriz (dando el número de 1 islas) y uno menos la matriz (dando el número de 0 islas). Para asegurarse de que los vecinos diagonales no cuenten como vecinos, se CornerNeighbors->Falsedebe dar la opción .

romano
fuente
-2 bytes ya que las desigualdades tienen mayor prioridad queRule
attinat
5

Python 3, 144127 bytes

Esta solución utiliza cv2el increíble poder de procesamiento de imágenes. A pesar de los nombres de métodos menos impresionantes, súper largos y legibles de cv, ¡supera a las otras dos respuestas de Python!

Golfizado:

import cv2,numpy as n
f=lambda b:n.amax(cv2.connectedComponents(b*255,0,4)[1])
def g(a):b=n.array(a,n.uint8);print(f(1-b),f(b))

Expandido:

import cv2
import numpy as np

# Finds the number of connected 1 regions 
def get_components(binary_map):
    _, labels = cv2.connectedComponents(binary_map*255, connectivity=4) # default connectivity is 8
    # labels is a 2d array of the binary map but with 0, 1, 2, etc. marking the connected regions
    components = np.amax(labels)
    return components

# Takes a 2d array of 0s and 1s and returns the number of connected regions
def solve(array): 
    binary_map = np.array(input_map, dtype=np.uint8)
    black_regions = get_components(1 - binary_map) # 0s
    white_regions = get_components(binary_map) # 1s
    return (black_regions, white_regions)
Daniel
fuente
No estoy muy familiarizado con Python, pero ¿por qué necesita los nombres de argumentos explícitos? ¿No es solo en 4lugar de connectivity=4y en n.uint8lugar de dtype=n.uint8posible?
Kevin Cruijssen
@KevinCruijssen, necesita los nombres de los argumentos si omite argumentos opcionales Echando un vistazo a los documentos, en realidad no tengo que saltar, lo que me ahorra muchos bytes. ¡Gracias!
Daniel
Ah, bueno, pensé que era algo así, pero cuando solo miré los documentos, solo pude encontrar un único cv2.connectedComponentsmétodo, así que estaba confundido y pensé que podría haber una razón diferente para necesitar los nombres de los argumentos. Como dije, no estoy muy familiarizado con Python. Todo lo que aprendí de él es de aquí en CCGC. ;) Pero tiene sentido usar los nombres de las variables para omitir otros argumentos opcionales.
Kevin Cruijssen
1
¡Muy agradable! Encontré un compilador en línea que incluye el módulo cv2 aquí .
Jitse
5

J , 46 44 43 bytes

-1 byte gracias a @miles

,&#&~.&([:+./ .*~^:_:2>1#.[:|@-"1/~4$.$.)-.

Pruébalo en línea!

pruebas y el ,& -.envoltorio robado de la respuesta de @ jonah

,& -. para la entrada y su negación hacer:

4$.$. (y, x) coordenadas de los 1 como una matriz n × 2

1#.[:|@-"1/~ distancias de manhattan: abs (∆x) + abs (∆y)

2> matriz vecina

[:+./ .*~^:_: clausura transitiva

#&~.&( ) número de filas únicas

ngn
fuente
1
puede componer la longitud única para guardar otro byte, es decir, ,&#&~.para evitar el límite[:
millas
@miles gracias
ngn
3

Retina 0.8.2 , 155 bytes

s`1(.*)
;$1a
}+`(?<=(.)*)(1|;)(.*¶(?<-1>.)*(?(1)$))?(?!\2)[1;]
;$3;
s`0(.*)
:$1b
}+`(?<=(.)*)(0|:)(.*¶(?<-1>.)*(?(1)$))?(?!\2)[0:]
:$3:
\W+(a*)(b*)
$.1 $.2

Pruébalo en línea! El enlace incluye un caso de prueba. Explicación:

s`1(.*)
;$1a

Si hay un 1, cámbielo ;y agregue un aal final de la entrada para que quede fuera del camino.

}+`(?<=(.)*)(1|;)(.*¶(?<-1>.)*(?(1)$))?(?!\2)[1;]
;$3;

Las inundaciones llenan más 1s adyacentes con ;s.

}

Repita hasta que todas las islas de 1s se hayan convertido en ;s.

s`0(.*)
:$1b

Si hay un 0, cámbielo :y agregue un bal final de la entrada para que quede fuera del camino.

+`(?<=(.)*)(0|:)(.*¶(?<-1>.)*(?(1)$))?(?!\2)[0:]
:$3:

Las inundaciones llenan más 0s adyacentes con :s.

}

Repita hasta que todas las islas de 0s se hayan convertido en :s.

\W+(a*)(b*)
$.1 $.2

Cuente por separado el número de islas de 1sy 0s.

Neil
fuente
3

Haskell , 228 227 225 224 bytes

import Data.List
z=zipWith
a!b=div(max(a*a)(a*b))a
l x=z(!)(z(!)x(0:x))$tail x++[0]
s=(\x->length.($x).filter<$>[(>0),(<0)]).nub.(>>=id).(until=<<((==)=<<))((.)>>=id$transpose.map l).z(\i->z(\j x->2^i*j*(2*x-1))[1,3..])[1..]

Pruébalo en línea!

Explicación:

La idea para esta solución es la siguiente: Inicialice la matriz con valores únicos en cada celda, positivos para 1y negativos para 0. Luego, compare repetidamente cada celda con sus vecinos y, si el vecino tiene el mismo signo pero un número con un valor absoluto mayor, reemplace el número de la celda con el número del vecino. Una vez que esto llegue a un punto fijo, cuente el número de números positivos distintos para el número de 1regiones y los números negativos distintos para el número de 0regiones.

En codigo:

s=(\x->length.($x).filter<$>[(>0),(<0)]).nub.(>>=id).(until=<<((==)=<<))((.)>>=id$transpose.map l).z(\i->z(\j x->2^i*j*(2*x-1))[1,3..])[1..]

se puede separar en el preprocesamiento (asignación de números a las celdas), la iteración y el posprocesamiento (recuento de celdas)

Preprocesamiento

La parte de preprocesamiento es la función

z(\i->z(\j x->2^i*j*(2*x-1))[1,3..])[1..]

Que se usa zcomo abreviatura para zipWithrecortar algunos bytes. Lo que hacemos aquí es comprimir la matriz bidimensional con índices enteros en las filas e índices enteros impares en las columnas. Hacemos esto ya que podemos construir un entero único a partir de un par de enteros (i,j)usando la fórmula (2^i)*(2j+1). Si solo generamos enteros impares j, podemos omitir el cálculo de2*j+1 , ahorrando tres bytes.

Con el número único, ahora solo tenemos que multiplicar en un signo basado en el valor en la matriz, que se obtiene como 2*x-1

Iteración

La iteración se realiza por

(until=<<((==)=<<))((.)>>=id$transpose.map l)

Dado que la entrada tiene la forma de una lista de listas, realizamos la comparación vecina en cada fila, transponemos la matriz, realizamos la comparación en cada fila nuevamente (que debido a la transposición es lo que eran las columnas antes) y volvemos a transponer. El código que cumple uno de estos pasos es

((.)>>=id$transpose.map l)

donde lestá la función de comparación (detallada a continuación) y transpose.map lrealiza la mitad de los pasos de comparación y transposición. (.)>>=idrealiza su argumento dos veces, siendo la forma sin puntos de \f -> f.fy en un byte más corto en este caso debido a las reglas de precedencia del operador.

lse define en la fila de arriba como l x=z(!)(z(!)x(0:x))$tail x++[0]. Este código realiza un operador de comparación (!)(ver más abajo) en cada celda con primero su vecino izquierdo, y luego con su vecino derecho, comprimiendo la lista xcon la lista desplazada hacia la derecha 0:xy la lista desplazada hacia la izquierda tail x++[0]. Usamos ceros para rellenar las listas desplazadas, ya que nunca pueden ocurrir en la matriz preprocesada.

a!bse define en la fila de arriba como esto a!b=div(max(a*a)(a*b))a. Lo que queremos hacer aquí es la siguiente distinción de casos:

  • Si sgn(a) = -sgn(b), tenemos dos áreas opuestas en la matriz y no deseamos unificarlas, entonces apermanece sin cambios
  • Si sgn(b) = 0, tenemos el caso de la esquina donde bestá el relleno y por lo tanto apermanece sin cambios
  • Si sgn(a) = sgn(b), deseamos unificar las dos áreas y tomar la que tenga el valor absoluto más grande (por conveniencia).

Tenga en cuenta que sgn(a)nunca puede ser 0. Logramos esto con la fórmula dada. Si los signos de ay bdifieren, a*bes menor o igual a cero, mientras a*aque siempre es mayor que cero, entonces lo elegimos como el máximo y dividimos con apara volver a. De lo contrario, max(a*a)(a*b)es abs(a)*max(abs(a),(abs(b)), y al dividir esto entre a, obtenemos sgn(a)*max(abs(a),abs(b)), que es el número con el valor absoluto más grande.

Para iterar la función ((.)>>=id$transpose.map l)hasta que alcanza un punto fijo, utilizamos (until=<<((==)=<<)), que se toma de esta respuesta stackoverflow .

Postprocesamiento

Para el posprocesamiento, utilizamos la parte

(\x->length.($x).filter<$>[(>0),(<0)]).nub.(>>=id)

que es solo una colección de pasos.

(>>=id)aplasta la lista de listas en una sola lista, nubelimina los dobles, (\x->length.($x).filter<$>[(>0),(<0)])divide la lista en un par de listas, una para números positivos y otra para números negativos, y calcula su longitud.

Sacchan
fuente
2

Java 10, 359 355 281 280 261 246 bytes

int[][]M;m->{int c[]={0,0},i=m.length,j,t;for(M=m;i-->0;)for(j=m[i].length;j-->0;)if((t=M[i][j])<2)c[t^1]+=f(t,i,j);return c;}int f(int v,int x,int y){try{if(M[x][y]==v){M[x][y]|=2;f(v,x+1,y);f(v,x,y+1);f(v,x-1,y);f(v,x,y-1);}}finally{return 1;}}

-74 bytes gracias a @NahuelFouilleul .

Pruébalo en línea.

Explicación:

int[][]M;              // Integer-matrix on class-level, uninitialized

m->{                   // Method with integer-matrix parameter and integer-array return-type
  int c[]={0,0}        //  Counters for the islands of 1s/0s, starting both at 0
      i=m.length,      //  Index of the rows
      j,               //  Index of the columns
      t;               //  Temp-value to decrease the byte-count
  for(M=m;             //  Set the class-level matrix to the input-matrix
      i-->0;)          //  Loop over the rows
    for(j=m[i].length;j-->0)
                       //   Inner loop over the columns
      if((t=M[i][j])   //    Set the temp value `t` to the value of the current cell
         <2)           //    And if this value is a 0 or 1:
        c[t^1]+=       //     Increase the corresponding counter by:
          f(t,i,j);    //      Call the recursive flood-fill method with value `t`
                       //      Which always returns 1 to increase the counter
  return c;}           //  After the nested loops: return the counters-array as result

// Recursive method with value and cell-coordinate as parameters,
// This method will flood-fill the matrix, where 0 becomes 2 and 1 becomes 3
int f(int v,int x,int y){
  try{if(M[x][y]==v){  //   If the cell contains the given value:
    M[x][y]|=2;        //    Fill the cell with 0→2 or 1→3 depending on the value
    f(v,x+1,y);        //    Do a recursive call downwards
    f(v,x,y+1);        //    Do a recursive call towards the right
    f(v,x-1,y);        //    Do a recursive call upwards
    f(v,x,y-1);}       //    Do a recursive call towards the left
  }finally{return 1;}} //  Ignore any ArrayIndexOutOfBoundsExceptions with a finally-return,
                       //  which is shorter than manual checks
                       //  And return 1 to increase the counter
Kevin Cruijssen
fuente
1
-74 bytes , eliminando el clon y usando |=2: 0 -> 2 y 1 -> 3, sin embargo, >0se cambió a==1
Nahuel Fouilleul
lo siento, tuve que eliminar las pruebas para que el enlace tio encajara en los comentarios
Nahuel Fouilleul
@NahuelFouilleul Gracias, inteligente usando |=2! Y aún podría usar en <2lugar de ==1-1 byte primero buscando 0(y así se cambian a 2, y luego usando <2para verificar 1(que se cambian a 3).
Kevin Cruijssen
2

Python 3 , 167 bytes

def f(m):
 n=[0,0];i=-2
 for r in m:
  j=0;i+=1
  for c in r:n[c^1]+=1-((i>=0)*(m[i][j]==c)*(1+({*r[:j]}=={c})*({*m[i][:j]}=={c^1}))or(j>0)*(r[j-1]==c));j+=1
 print(n)

Pruébalo en línea!


Python 2 , 168 bytes

def f(m):
 n=[0,0];i=-2
 for r in m:
	j=0;i+=1
	for c in r:n[c^1]+=1-((i>=0)*(m[i][j]==c)*(1+(set(r[:j])=={c})*(set(m[i][:j])=={c^1}))or(j>0)*(r[j-1]==c));j+=1
 print n

Pruébalo en línea!

-2 bytes gracias a Kevin Cruijssen

Solución de formato de +2 bytes

Explicación

Se mantiene un contador durante 0s y 1s. Para cada entrada en la matriz, se realizan las siguientes acciones:

  • Contador de incrustaciones para el valor actual en 1
  • Si el mismo valor existe directamente arriba o a la izquierda, disminuya en 1

Esto da como resultado un falso positivo para casos alineados a la izquierda como

0 0 1
1 1 1

o

0 1
1 1

Si surge tal situación, el contador se reduce en 1.

El valor de retorno es [#1, #0]

Jitse
fuente
1
Me temo que el OP mencionado en el segundo comentario debería ser el orden [#1, #0]. No tiene sentido imo para hacer cumplir esto, pero es lo que es por ahora. De todos modos, se puede jugar golf del {not c}a {c^1}, y solucionar el problema que he mencionado al cambiar n[c]+=a n[c^1]+=una cuestión similar. Buena respuesta, sin embargo, +1 de mi parte. :)
Kevin Cruijssen
Ah, tienes razon. ¡Gracias!
Jitse
1

Perl 5 (-0777p ), 110 bytes

Se puede mejorar, usa una expresión regular para reemplazar 1con 3, luego 0con 2.

/
/;$m="(.{@-})?";sub f{($a,$b,$c)=@_;1while s/$b$m\K$a|$a(?=$m$b)/$b/s||s/$a/$b/&&++$c;$c}$_=f(1,3).$".f(0,2)

TIO

Nahuel Fouilleul
fuente
1

Jalea , 44 36 bytes

ŒJfⱮ+€¥Ø.,UŻ¤œịƇþ,¬$¹ƇfƇⱮ`ẎQ$€QƲÐL€Ẉ

Pruébalo en línea!

Un enlace monádico que acepta una lista de listas de enteros como argumento y devuelve una lista del número de islas 1 y 0 en ese orden.

Explicación

Paso 1

Genere una lista de todos los índices de la matriz, cada uno con los índices de su vecino a la derecha (a menos que esté en el lado derecho) y hacia abajo (a menos que esté al final)

ŒJ            | Multi-dimensional indices (e.g. [1,1],[1,2],[1,3],[2,1],[2,2],[2,3])
      ¥       | Following as as a dyad:
  fⱮ          | - Filter the indices by each of:
    +€      ¤ |   - The indices added to the following
       Ø.     |     - 0,1
         ,U   |     - Paired with itself reversed [0,1],[1,0]
           Ż  |     - Prepended with zero 0,[0,1],[1,0]

Paso 2

Divida estos índices por si había 1 o 0 en la entrada. Devuelve una lista de índices con vecinos para 1s y otra para 0s.

  Ƈþ   | Filter each member of the output of stage 1 using the following criteria:
œị   $ | - Corresponding value for the multi-dimensional indices in each of the following as a monad:
   ,¬  |   - The input paired with its inverse

Paso 3

Combinar listas con miembros en recuentos comunes y de salida

           ƲÐL€  | For each of the outputs from stage 2, do the following as a monad and repeat until no changes
¹Ƈ               | - Filter out empty lists (only needed on first pass through but included here to save a byte)         
  fƇⱮ`           | - Take each list of indices and filter the list of indices for those containing a match for any of them
        $€       | - For each resulting list of lists:
      Ẏ          |   - Tighten (concatenate top level of lists)
       Q         |   - Uniquify
          Q      | - Uniquify
               Ẉ | Finally output the lengths of the final lists
Nick Kennedy
fuente
1

T-SQL 2008, 178 bytes

La entrada es una variable de tabla.

x e y son las coordenadas

v son los valores 0 y 1 (también podría manejar otros valores numéricos)

Los datos de prueba utilizados en este ejemplo:

100
000
001
DECLARE @ table(x int, y int, v int)

INSERT @ values
(1,1,1),(1,2,0),(1,3,0),
(2,1,0),(2,2,0),(2,3,0),
(3,1,0),(3,2,0),(3,3,1)
SELECT*,y-x*99r INTO # FROM @
WHILE @@rowcount>0UPDATE #
SET r=b.r
FROM #,# b
WHERE abs(#.x-b.x)+abs(#.y-b.y)=1and #.v=b.v and #.r>b.r
SELECT v,count(distinct r)FROM #
GROUP BY v

Pruébalo en línea

t-clausen.dk
fuente
1

R , 194 172 bytes

function(m,u=!1:2){for(i in 1:2){w=which(m==i-1,T)
N=1:nrow(w)
A=!!N
for(s in N){u[i]=u[i]+A[s]
while(any(s)){A[s]=F
s=c(N[as.matrix(dist(w))[s[1],]==1&A],s[-1])}}}
rev(u)}

Pruébalo en línea!

Realice una búsqueda de profundidad primero comenzando en cada celda de la matriz que sea igual a 1 (o cero).

  • -2 bytes gracias a @Giuseppe
digEmAll
fuente