Para encontrar ilhas de 1 e 0 na matriz

29

Dada uma matriz bidimensional de 0 e 1s. Encontre o número de ilhas para 1s e 0s em que os vizinhos estão apenas na horizontal e na 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
Alegria KB
fonte
11
Você deve adicionar um caso de teste [[1,0];[0,1]]para garantir que a conectividade diagonal não esteja incluída.
Sanchises 28/07
8
Eu sugiro que a saída possa estar em qualquer ordem, desde que a ordem seja especificada - não agrega nenhum valor para forçar uma ordem
streetster
8
Bem vindo ao site!
Arnauld
11
O que foi respondido nos comentários deve ser esclarecido no corpo do desafio. E, mais especificamente, se você realmente deseja que retornemos 1 antes de 0, deve ser claramente indicado.
Arnauld
4
Caso de teste sugerido: 11111 / 10001 / 10101 / 10001 / 111112 1
Kevin Cruijssen

Respostas:

16

APL (Dyalog Unicode) , 29 28 bytes SBCS

-1 graças a @ Adám

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

Experimente online!

⊂,~∘⊂ a matriz e sua negação

{ para cada um deles

⍸⍵ lista de pares de cordas de 1s

+/↑|∘.-⍨ matriz de distâncias de manhattan

2> matriz vizinha

∨.∧⍨⍣≡ fechamento transitivo

≢∪ número de linhas exclusivas

ngn
fonte
isso é realmente inteligente. você poderia explicar por que a linha final está garantida para funcionar - ou seja, por que linhas exclusivas são equivalentes à resposta. Além disso, o "fechamento transitivo" é como o de J ^:_?
Jonah
11
@Jonah see chat
ngn
16

J , 57 bytes

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

Experimente online!

Esse é um daqueles em que a ideia é incrivelmente simples (e eu acho divertida), mas a execução teve alguma longitude mecânica que mascara a simplicidade ... por exemplo, mudar a matriz original em todas as direções com 0 preenchimento é detalhado ((,-)#:i.3) |.!.0 .

É provável que essa longevidade mecânica possa ser ainda mais aprimorada, e posso tentar amanhã à noite, mas vou postar o ponto crucial agora.

Digamos que nossa opinião é:

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

Começamos com uma matriz de números inteiros únicos do mesmo tamanho:

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

Então, para cada célula, encontramos o máximo de todos os seus vizinhos e multiplicamos pela máscara de entrada:

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

Nós iteramos esse processo até que a matriz pare de mudar:

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

E conte o número de elementos únicos, diferentes de zero. Isso nos diz o número de 1 ilhas.

Aplicamos o mesmo processo a "1 menos a entrada" para obter o número de 0 ilhas.

Jonah
fonte
3
Isso se parece muito com um mecanismo de "preenchimento", realmente limpo.
Matthieu M.
7

JavaScript (ES7),  138 ... 107  106 bytes

Retorna uma 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

Experimente online!

Quão?

Usamos uma função recursiva. Durante a chamada inicial, procuramos 0 e 1 1 . Sempre que encontramos esse ponto de partida, incrementamos o contador da ilha correspondente ( c[0 0] ou c[1 1] ) e entramos na fase recursiva para preencher a área de células adjacentes semelhantes com 2 's.

Para salvar bytes, o mesmo código exato é usado para a iteração raiz e as iterações recursivas, mas se comporta de maneira um pouco diferente.

Durante a primeira iteração:

  • Começamos com V=0.5 para que Vv seja arredondado para 0 para v=0 e v=1 , graças ao OR bit a bit.
  • X eY são indefinidos e a quadrância computada (x-X)2+(y-Y)2 avaliada para NaN . Isso força o teste de desigualdade a falhar, não importa o valor de (x,y) .

Durante as iterações recursivas:

  • O parâmetro c é definido como um número inteiro ( 2c[v ^ 1]++c

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
fonte
Esse código não funciona para matrizes grandes como 100 * 100, com apenas 1s ou 0s devido ao estouro da pilha.
KB joy
3
@KBjoy A menos que seja explicitamente especificado o contrário no desafio, nossa regra padrão é que não nos importemos com os limites de implementação, desde que o algoritmo subjacente funcione na teoria para qualquer entrada. ( Aqui está um post meta sobre isso, mas há provavelmente um lugar mais relevante.)
Arnauld
7

MATL , 14 12 bytes

,G@-K&1ZIugs

Experimente online!Ou verifique todos os casos de teste .

Explicação

,        % 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
fonte
6

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

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

Experimente online!

~:\ um par de entrada e sua negação (literalmente: negar iterar-convergir)

{ }' para cada

,/x achatar o arg

&onde estão os 1s? - lista de índices

(0,#*x)\ divmod width (input) para obter duas listas separadas para ys e xs

x-\:'x: distâncias por eixo ∆x e ∆y

x*x: esquadrá-los

+/ adicione ∆x² e ∆y²

2> matriz vizinha

{|/'x*\:x}/ fechamento transitivo

#? contar linhas únicas

ngn
fonte
Depois de ver sua resposta, fico feliz por não ter tentado resolver essa questão em K :)
streetster
2
@streetster haha, obrigado! esse não é o efeito que eu pretendia :) Na verdade, eu gostaria de incentivar as pessoas a aprender (qualquer dialeto de) e golfe nele
ngn
6

Wolfram Language (Mathematica) , 64 62 bytes

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

Experimente online!

Graças a attinat : podemos escrever em 1<0vez deFalse e salvar dois bytes.

versão sem golfe:

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

Obviamente, existe um Mathematica embutido MorphologicalComponentsque pega uma matriz (ou uma imagem) e retorna o mesmo com os pixels de cada ilha morfologicamente conectada substituídos pelo índice da ilha. Obter Maxeste resultado fornece o número de ilhas (os zeros de fundo são deixados em zero e o índice da ilha começa em 1). Precisamos fazer isso separadamente para a matriz (fornecendo o número de 1 ilhas) e um menos a matriz (fornecendo o número de 0 ilhas). Para garantir que os vizinhos diagonais não contam como vizinhos, a opção CornerNeighbors->Falseprecisa ser dada.

romano
fonte
-2 bytes, uma vez que as desigualdades têm maior precedência do queRule
attinat 29/07
5

Python 3, 144 127 bytes

Esta solução usa cv2 o incrível poder de processamento de imagem. Apesar dos nomes de métodos menos impressionantes, super longos e legíveis do cv, ele supera as outras respostas em Python!

Golfe:

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
fonte
Eu não estou muito familiarizado com Python, mas por que você precisa dos nomes explícitos dos argumentos? Não é apenas em 4vez de connectivity=4e em n.uint8vez de dtype=n.uint8possível?
Kevin Cruijssen 29/07
@KevinCruijssen, você precisará dos nomes dos argumentos se ignorar argumentos opcionais. Dando uma olhada nos documentos, na verdade não preciso pular, o que me poupa muitos bytes. Obrigado!
Daniel
Ah, ok, eu pensei que era algo assim, mas quando eu apenas olhei os documentos, só consegui encontrar um único cv2.connectedComponentsmétodo, então fiquei confuso e pensei que poderia haver uma razão diferente para precisar os nomes dos argumentos. Como eu disse, não estou muito familiarizado com o Python. Tudo o que aprendi com isso é daqui no CCGC. ;) Mas faz sentido usar os nomes das variáveis ​​para pular outros argumentos opcionais.
Kevin Cruijssen 29/07
11
Muito agradável! Encontrei um compilador online que inclui o módulo cv2 aqui .
Jitse 29/07
5

J , 46 44 43 bytes

-1 byte graças a @miles

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

Experimente online!

testes e o ,& -.invólucro roubado da resposta de @ jonah

,& -. para a entrada e sua negação:

4$.$. (y, x) coordenadas dos 1s como uma matriz n × 2

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

2> matriz vizinha

[:+./ .*~^:_: fechamento transitivo

#&~.&( ) número de linhas exclusivas

ngn
fonte
11
você pode compor o comprimento e única para salvar outro byte, ou seja, ,&#&~.para evitar a tampa[:
milhas
@miles obrigado
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

Experimente online! O link inclui caso de teste. Explicação:

s`1(.*)
;$1a

Se houver um 1 , altere-o para ;e inclua um ano final da entrada para que fique fora do caminho.

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

Inundação encher mais adjacente 1 s com ;s.

}

Repita até todas as ilhas de 1 s sejam transformadas em ;s.

s`0(.*)
:$1b

Se houver 0, mude para: e inclua ba no final da entrada para que fique fora do caminho.

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

Inundação encher mais adjacente 0 s com :s.

}

Repita até todas as ilhas de 0 s sejam transformadas em :s.

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

Contar separadamente o número de ilhas de 1 s e 0s.

Neil
fonte
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..]

Experimente online!

Explicação:

A idéia para esta solução é a seguinte: Inicialize a matriz com valores exclusivos em cada célula, positivos para 1 e negativos para 0. Em seguida, compare repetidamente cada célula com seus vizinhos e, se o vizinho tiver o mesmo sinal, mas um número com um valor absoluto maior, substitua o número da célula pelo número do vizinho. Quando isso atingir um ponto fixo, conte o número de números positivos distintos para o número de 1regiões e os números negativos distintos para o número de0 regiões.

Em código:

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..]

pode ser separado no pré-processamento (atribuindo números às células), na iteração e no pós-processamento (contagem de células)

Pré-processando

A parte de pré-processamento é a função

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

Que usa zcomo abreviação para zipWithraspar alguns bytes. O que fazemos aqui é compactar a matriz bidimensional com índices inteiros nas linhas e índices inteiros ímpares nas colunas. Fazemos isso, pois podemos construir um número inteiro único a partir de um par de números inteiros (i,j)usando a fórmula (2^i)*(2j+1). Se gerarmos números inteiros ímpares para j, podemos pular o cálculo da2*j+1 , economizando três bytes.

Com o número único, agora precisamos multiplicar apenas um sinal com base no valor da matriz, que é obtido como 2*x-1

Iteração

A iteração é feita por

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

Como a entrada está na forma de uma lista de listas, realizamos a comparação de vizinhos em cada linha, transpomos a matriz, realizamos a comparação em cada linha novamente (que devido à transposição é o que eram as colunas anteriores) e transpomos novamente. O código que realiza uma dessas etapas é

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

onde lé a função de comparação (detalhada abaixo) e transpose.map lexecuta metade das etapas de comparação e transposição. (.)>>=idexecuta seu argumento duas vezes, sendo a forma sem pontos \f -> f.fe um byte mais curta nesse caso, devido às regras de precedência do operador.

lé definido na linha acima como l x=z(!)(z(!)x(0:x))$tail x++[0]. Esse código executa um operador de comparação (!)(veja abaixo) em todas as células com o primeiro vizinho esquerdo e, depois, com o vizinho direito, fechando a lista xcom a lista deslocada à direita 0:xe a lista deslocada à esquerdatail x++[0] . Usamos zeros para preencher as listas deslocadas, pois elas nunca podem ocorrer na matriz pré-processada.

a!bé definido na linha acima disso como a!b=div(max(a*a)(a*b))a. O que queremos fazer aqui é a seguinte distinção entre casos:

  • Se sgn(a) = -sgn(b)tivermos duas áreas opostas na matriz e não desejarmos unificá-las, apermaneceremos inalteradas
  • Se sgn(b) = 0, temos a caixa de canto onde bestá o preenchimento e, portanto, apermanece inalterada
  • Se sgn(a) = sgn(b)desejarmos unificar as duas áreas e escolher a que tiver o maior valor absoluto (por conveniência).

Note que sgn(a)nunca pode ser 0. Conseguimos isso com a fórmula dada. Se os sinais de ae bdiferem, a*bé menor ou igual a zero, enquanto a*aé sempre maior que zero, então escolhemos o máximo e dividimos com apara voltar a. Caso contrário, max(a*a)(a*b)é abs(a)*max(abs(a),(abs(b)), e dividindo isso por a, obtemos sgn(a)*max(abs(a),abs(b)), que é o número com o valor absoluto maior.

Para iterar a função ((.)>>=id$transpose.map l)até que ela atinja um ponto fixo, usamos o (until=<<((==)=<<))que é retirado dessa resposta do stackoverflow .

Pós-processamento

Para pós-processamento, usamos a parte

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

que é apenas uma coleção de etapas.

(>>=id)esmaga a lista de listas em uma única lista, nubelimina duplas, (\x->length.($x).filter<$>[(>0),(<0)])divide a lista em um par de listas, uma para números positivos e outra para números negativos, e calcula seus comprimentos.

Sacchan
fonte
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 graças a @NahuelFouilleul .

Experimente online.

Explicação:

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
fonte
11
-74 bytes , removendo o clone e usando |=2: 0 -> 2 e 1 -> 3, no entanto, >0foi alterado para==1
Nahuel Fouilleul
desculpe, eu tive que remover os testes para que o link do tio caiba nos comentários
Nahuel Fouilleul
@NahuelFouilleul Obrigado, usando inteligente |=2! E eu ainda poderia usar <2em vez de ==1para -1 byte a primeira verificação para 0(e, portanto, eles são alterados para 2, em seguida, usando o <2para verificar se há 1(que são alterados para 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)

Experimente online!


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

Experimente online!

-2 bytes graças a Kevin Cruijssen

Correção de formatação de +2 bytes

Explicação

Um contador é mantido por 0s e 1s. Para cada entrada na matriz, são executadas as seguintes ações:

  • Contador Incrase para o valor atual em 1
  • Se o mesmo valor existir diretamente acima ou à esquerda, diminua 1

Isso resulta em um falso positivo para casos alinhados à esquerda, como

0 0 1
1 1 1

ou

0 1
1 1

Se essa situação surgir, o contador será reduzido em 1.

O valor de retorno é [#1, #0]

Jitse
fonte
11
Receio que o OP mencionado no segundo comentário seja o pedido [#1, #0]. Imo pouco inútil para impor isso, mas é o que é por agora. De qualquer forma, você pode golfe do {not c}que{c^1} , e corrigir o problema que mencionei, alterando n[c]+=a n[c^1]+=em uma matéria similar. Boa resposta, porém, +1 de mim. :)
Kevin Cruijssen 29/07
Ah, você está certo. Obrigado!
Jitse 29/07
1

Perl 5 (-0777p ), 110 bytes

Pode ser aprimorado, usa um regex para substituir 1por 3e depois 0por 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
fonte
1

Geléia , 44 36 bytes

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

Experimente online!

Um link monádico que aceita uma lista de listas de números inteiros como argumento e retorna uma lista do número de ilhas 1 e 0 nessa ordem.

Explicação

Passo 1

Gere uma lista de todos os índices da matriz, cada um com os índices de seu vizinho à direita (a menos que esteja do lado direito) e para baixo (a menos que esteja na parte inferior)

Œ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]

Passo 2

Divida esses índices se houve 1 ou 0 na entrada. Retorna uma lista de índices com vizinhos para 1s e outra 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

etapa 3

Mesclar listas com membros em contagens comuns e de saída

           ƲÐ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
fonte
1

T-SQL 2008, 178 bytes

Entrada é uma variável de tabela.

x e y são as coordenadas

v são os valores 0 e 1 (também podem manipular outros valores numéricos)

Os dados de teste usados ​​neste exemplo:

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

Experimente online

t-clausen.dk
fonte
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)}

Experimente online!

Execute uma pesquisa aprofundada iniciando em cada célula da matriz igual a 1 (ou zero).

  • -2 bytes graças a @ Giuseppe
digEmAll
fonte