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
code-golf
binary-matrix
KB alegría
fuente
fuente
[[1,0];[0,1]]
para asegurarse de que la conectividad diagonal no esté incluida11111 / 10001 / 10101 / 10001 / 11111
→2 1
Respuestas:
APL (Dyalog Unicode) ,
2928 bytes SBCS-1 gracias a @ Adám
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 manhattan2>
matriz vecina∨.∧⍨⍣≡
clausura transitiva≢∪
número de filas únicasfuente
^:_
?J , 57 bytes
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:
Comenzamos con una matriz de enteros únicos del mismo tamaño:
Luego, para cada celda, encontramos el máximo de todos sus vecinos y lo multiplicamos por la máscara de entrada:
Repetimos este proceso hasta que la matriz deja de cambiar:
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.
fuente
JavaScript (ES7),
138 ...107106 bytesDevuelve una matriz
[ones, zeros]
.Pruébalo en línea!
¿Cómo?
Usamos una función recursiva. Durante la llamada inicial, buscamos0 0 y 1 . Cada vez que encontramos ese punto de partida, incrementamos el contador de la isla correspondiente ( c [ 0 ] oc [ 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:
Durante las iteraciones recursivas:
c[v ^ 1]++
Comentado
fuente
MATL ,
1412 bytesPruébalo en línea! O verificar todos los casos de prueba .
Explicación
fuente
K (ngn / k) ,
60 55 51 5046 bytesPrué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 xsx-\:'x:
distancias por eje ∆x y ∆yx*x:
cuadrarlos+/
agregue ∆x² y ∆y²2>
matriz vecina{|/'x*\:x}/
clausura transitiva#?
contar filas únicasfuente
Wolfram Language (Mathematica) ,
6462 bytesPruébalo en línea!
Gracias a attinat : podemos escribir en
1<0
lugar deFalse
y guardar dos bytes.versión sin golf:
Existe, por supuesto, un componente integrado de Mathematica
MorphologicalComponents
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 elMax
resultado 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, seCornerNeighbors->False
debe dar la opción .fuente
Rule
Python 3,
144127bytesEsta solución utiliza
cv2
el 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:
Expandido:
fuente
4
lugar deconnectivity=4
y enn.uint8
lugar dedtype=n.uint8
posible?cv2.connectedComponents
mé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.J ,
46 4443 bytes-1 byte gracias a @miles
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 × 21#.[:|@-"1/~
distancias de manhattan: abs (∆x) + abs (∆y)2>
matriz vecina[:+./ .*~^:_:
clausura transitiva#&~.&(
)
número de filas únicasfuente
,&#&~.
para evitar el límite[:
Retina 0.8.2 , 155 bytes
Pruébalo en línea! El enlace incluye un caso de prueba. Explicación:
Si hay un
1
, cámbielo;
y agregue una
al final de la entrada para que quede fuera del camino.Las inundaciones llenan más
1
s adyacentes con;
s.Repita hasta que todas las islas de
1
s se hayan convertido en;
s.Si hay un
0
, cámbielo:
y agregue unb
al final de la entrada para que quede fuera del camino.Las inundaciones llenan más
0
s adyacentes con:
s.Repita hasta que todas las islas de
0
s se hayan convertido en:
s.Cuente por separado el número de islas de
1
sy0
s.fuente
Haskell ,
228227225224 bytesPrué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
1
y negativos para0
. 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 de1
regiones y los números negativos distintos para el número de0
regiones.En codigo:
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
Que se usa
z
como abreviatura parazipWith
recortar 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 imparesj
, 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
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
l
está la función de comparación (detallada a continuación) ytranspose.map l
realiza la mitad de los pasos de comparación y transposición.(.)>>=id
realiza su argumento dos veces, siendo la forma sin puntos de\f -> f.f
y en un byte más corto en este caso debido a las reglas de precedencia del operador.l
se define en la fila de arriba comol 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 listax
con la lista desplazada hacia la derecha0:x
y la lista desplazada hacia la izquierdatail x++[0]
. Usamos ceros para rellenar las listas desplazadas, ya que nunca pueden ocurrir en la matriz preprocesada.a!b
se define en la fila de arriba como estoa!b=div(max(a*a)(a*b))a
. Lo que queremos hacer aquí es la siguiente distinción de casos:sgn(a) = -sgn(b)
, tenemos dos áreas opuestas en la matriz y no deseamos unificarlas, entoncesa
permanece sin cambiossgn(b) = 0
, tenemos el caso de la esquina dondeb
está el relleno y por lo tantoa
permanece sin cambiossgn(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 ser0
. Logramos esto con la fórmula dada. Si los signos dea
yb
difieren,a*b
es menor o igual a cero, mientrasa*a
que siempre es mayor que cero, entonces lo elegimos como el máximo y dividimos cona
para volvera
. De lo contrario,max(a*a)(a*b)
esabs(a)*max(abs(a),(abs(b))
, y al dividir esto entrea
, obtenemossgn(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
que es solo una colección de pasos.
(>>=id)
aplasta la lista de listas en una sola lista,nub
elimina 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.fuente
Java 10,
359355281280261246 bytes-74 bytes gracias a @NahuelFouilleul .
Pruébalo en línea.
Explicación:
fuente
|=2
: 0 -> 2 y 1 -> 3, sin embargo,>0
se cambió a==1
|=2
! Y aún podría usar en<2
lugar de==1
-1 byte primero buscando0
(y así se cambian a2
, y luego usando<2
para verificar1
(que se cambian a3
).Python 3 , 167 bytes
Pruébalo en línea!
Python 2 , 168 bytes
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:
Esto da como resultado un falso positivo para casos alineados a la izquierda como
o
Si surge tal situación, el contador se reduce en 1.
El valor de retorno es
[#1, #0]
fuente
[#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 cambiarn[c]+=
an[c^1]+=
una cuestión similar. Buena respuesta, sin embargo, +1 de mi parte. :)Perl 5 (
-0777p
), 110 bytesSe puede mejorar, usa una expresión regular para reemplazar
1
con3
, luego0
con2
.TIO
fuente
Jalea ,
4436 bytesPrué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)
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.
Paso 3
Combinar listas con miembros en recuentos comunes y de salida
fuente
T-SQL 2008, 178 bytes
La entrada es una variable de tabla.
Los datos de prueba utilizados en este ejemplo:
Pruébalo en línea
fuente
R ,
194172 bytesPrué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).
fuente