Per trovare isole di 1 e 0 in matrice


29

Data una matrice bidimensionale di 0 e 1s. Trova il numero di isole per 1 e 0 dove i vicini sono solo in orizzontale e verticale.

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

11
Dovresti aggiungere un testcase come [[1,0];[0,1]]per assicurarti che la connettività diagonale non sia inclusa
Sanchises

8
Suggerirei che l'output può essere in entrambi gli ordini fintanto che l'ordine è specificato - non aggiunge alcun valore per forzare un ordine
streetster

8
Benvenuti nel sito!
Arnauld,

1
Ciò che è stato risposto nei commenti dovrebbe essere chiarito nel corpo della sfida. E più specificamente, se vuoi davvero che restituiamo 1 prima degli 0, dovrebbe essere indicato chiaramente.
Arnauld,

4
Caso di prova suggerito: 11111 / 10001 / 10101 / 10001 / 111112 1
Kevin Cruijssen il

Risposte:


16

APL (Dyalog Unicode) , 29 28 byte SBCS

-1 grazie a @ Adám

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

Provalo online!

⊂,~∘⊂ la matrice e la sua negazione

{ per ognuno di loro

⍸⍵ elenco di coppie di corde di 1s

+/↑|∘.-⍨ matrice delle distanze di manhattan

2> matrice vicina

∨.∧⍨⍣≡ chiusura transitiva

≢∪ numero di righe univoche


questo è davvero intelligente. potresti approfondire il motivo per cui la linea finale è garantita per funzionare, ovvero perché le righe univoche equivalgono alla risposta. inoltre, la "chiusura transitiva" è come quella di J ^:_?
Giona il

1
@Jonah vedi chat
ngn

16

J , 57 byte

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

Provalo online!

Questo è uno di quelli in cui l'idea è incredibilmente semplice (e penso divertente), ma eseguirla ha avuto una certa longevità meccanica che maschera la semplicità ... ad esempio, spostare la matrice originale in tutte le direzioni con 0 fill è il verboso ((,-)#:i.3) |.!.0 .

È probabile che questa lunghezza meccanica possa essere ulteriormente approfondita, e potrei provare domani sera, ma pubblicherò il punto cruciale ora.

Supponiamo che il nostro input sia:

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

Iniziamo con una matrice di numeri interi univoci delle stesse dimensioni:

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

Quindi per ogni cella troviamo il massimo di tutti i suoi vicini e moltipliciamo per la maschera di input:

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

Ripetiamo questo processo fino a quando la matrice smette di cambiare:

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

E quindi contare il numero di elementi unici, diversi da zero. Questo ci dice il numero di 1 isole.

Applichiamo lo stesso processo a "1 meno l'input" per ottenere il numero di 0 isole.


3
Questo assomiglia molto a un meccanismo di "alluvione", davvero pulito.
Matthieu M.

7

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

Restituisce un array [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

Provalo online!

Come?

01c[0]c[1]2

Per salvare i byte, viene utilizzato lo stesso codice esatto sia per l'iterazione radice che per le iterazioni ricorsive, ma si comporta in modo leggermente diverso.

Durante la prima iterazione:

  • V=0.5V-v0v=0v=1
  • XY(xX)2+(yY)2(x,y)

Durante le iterazioni ricorsive:

  • c2c[v ^ 1]++c

Commentate

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

Questo codice non funziona per matrici di grandi dimensioni come 100 * 100, con solo 1 o 0 a causa di overflow dello stack.
KB gioia

3
@KBjoy Se non diversamente specificato nella sfida, la nostra regola predefinita è che non ci preoccupiamo dei limiti di implementazione fintanto che l'algoritmo sottostante funziona in teoria per qualsiasi input. ( Ecco un meta post a riguardo, ma probabilmente ce n'è uno più pertinente da qualche parte.)
Arnauld

7

MATL , 14 12 byte

,G@-K&1ZIugs

Provalo online! Oppure verifica tutti i casi di test .

Spiegazione

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

6

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

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

Provalo online!

~:\ una coppia di input e la sua negazione (letteralmente: negate iterate-converge)

{ }' per ciascuno

,/x appiattire l'arg

&dove sono gli 1? - elenco di indici

(0,#*x)\ divmod width (input) per ottenere due elenchi separati per ys e xs

x-\:'x: distanze per asse ∆x e ∆y

x*x: quadrali

+/ aggiungere ∆x² e ∆y²

2> matrice vicina

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

#? contare righe univoche


Dopo aver visto la tua risposta, sono contento di non aver provato ad affrontarlo in K :)
Stradina il

2
@streetster haha, grazie! non è l'effetto che intendevo :) Vorrei davvero incoraggiare le persone ad imparare (qualsiasi dialetto di) k e giocare a golf
ngn

6

Wolfram Language (Mathematica) , 64 62 byte

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

Provalo online!

Grazie ad attinat : possiamo scrivere 1<0invece diFalse e salvare due byte.

versione senza golf:

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

Esiste ovviamente un built-in MathematicaMorphologicalComponents che prende un array (o un'immagine) e restituisce lo stesso con i pixel di ciascuna isola morfologicamente connessa sostituita dall'indice dell'isola. Prendendo Maxquesto risultato si ottiene il numero di isole (gli zeri di sfondo vengono lasciati a zero e l'indice dell'isola inizia da 1). Dobbiamo farlo separatamente per l'array (fornendo il numero di 1 isole) e uno meno l'array (fornendo il numero di 0 isole). Per assicurarsi che i vicini diagonali non contino come vicini, l'opzione CornerNeighbors->Falsedeve essere data.


-2 byte poiché le disuguaglianze hanno una precedenza più alta diRule
attinat

5

Python 3, 144 127 byte

Questa soluzione utilizza cv2 la straordinaria potenza di elaborazione delle immagini. Nonostante i nomi dei metodi meno fantastici, super lunghi e leggibili del cv, batte entrambe le altre risposte di Python!

golfed:

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

Allargato:

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)

Non ho troppa familiarità con Python, ma perché hai bisogno dei nomi degli argomenti espliciti? Non è solo 4invece di connectivity=4e n.uint8invece di dtype=n.uint8possibile?
Kevin Cruijssen,

@KevinCruijssen, hai bisogno dei nomi degli argomenti se salti argomenti opzionali. Dando un'occhiata ai documenti, in realtà non devo saltare, il che mi fa risparmiare un sacco di byte. Grazie!
Daniel,

Ah ok, ho pensato che fosse qualcosa del genere, ma quando ho appena guardato i documenti sono riuscito a trovare solo un singolo cv2.connectedComponentsmetodo, quindi ero confuso e ho pensato che ci potesse essere un motivo diverso per aver bisogno dei nomi degli argomenti. Come ho detto, non ho troppa familiarità con Python. Tutto quello che ho imparato da questo è da qui su CCGC. ;) Ma ha senso usare i nomi delle variabili per saltare altri argomenti opzionali.
Kevin Cruijssen,

1
Molto bella! Ho trovato un compilatore online che include il modulo cv2 qui .
Jitse,

5

J , 46 44 43 byte

-1 byte grazie a @miles

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

Provalo online!

test e il ,& -.wrapper rubato dalla risposta di @jonah

,& -. per l'input e la sua negazione fare:

4$.$. (y, x) coordinate degli 1 come matrice n × 2

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

2> matrice vicina

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

#&~.&( ) numero di righe univoche


1
è possibile comporre la lunghezza e l'unicità per salvare un altro byte, ovvero ,&#&~.per evitare il limite[:
miglia

@miles grazie
ngn

3

Retina 0.8.2 , 155 byte

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

Provalo online! Il collegamento include un test case. Spiegazione:

s`1(.*)
;$1a

Se c'è un 1, cambiarlo in ;e aggiungere un aalla fine dell'input in modo che sia fuori mano.

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

Riempi tutte le altre adiacenti 1con ;s.

}

Ripeti fino a quando tutte le isole di 1s sono state trasformate in ;s.

s`0(.*)
:$1b

Se c'è un 0, cambiarlo in :e aggiungere ba alla fine dell'input in modo che sia fuori mano.

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

Riempi tutte le altre adiacenti 0con :s.

}

Ripeti fino a quando tutte le isole di 0s sono state trasformate in :s.

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

Separatamente contare il numero di isole di 1s e 0s.


3

Haskell , 228 227 225 224 byte

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

Provalo online!

Spiegazione:

L'idea per questa soluzione è la seguente: Inizializza la matrice con valori univoci in ogni cella, positiva per 1e negativa per 0. Quindi confronta ripetutamente ogni cella con i suoi vicini e, se il vicino ha lo stesso segno ma un numero con un valore assoluto più grande, sostituisci il numero della cella con il numero del vicino. Una volta che questo raggiunge un punto fisso, conta il numero di numeri positivi distinti per il numero di 1regioni e i numeri negativi distinti per il numero di0 regioni.

Nel codice:

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

può essere separato nella preelaborazione (assegnazione dei numeri alle celle), nell'iterazione e nella postelaborazione (conteggio delle celle)

Pre-elaborazione

La parte di preelaborazione è la funzione

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

Che usa zcome abbreviazione per zipWithradere qualche byte. Quello che facciamo qui è comprimere l'array bidimensionale con indici di numero intero nelle righe e indici di numero intero dispari nelle colonne. Lo facciamo poiché possiamo costruire un numero intero univoco da una coppia di numeri interi (i,j)usando la formula (2^i)*(2j+1). Se generiamo solo numeri dispari per j, possiamo saltare il calcolo 2*j+1, salvando tre byte.

Con il numero univoco, ora non ci resta che moltiplicare per un segno basato sul valore nella matrice, che si ottiene come 2*x-1

Iterazione

L'iterazione è eseguita da

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

Poiché l'input ha la forma di un elenco di elenchi, eseguiamo il confronto adiacente su ogni riga, trasponiamo la matrice, eseguiamo nuovamente il confronto su ogni riga (che a causa del recepimento è ciò che era le colonne prima) e trasponiamo nuovamente. Il codice che compie uno di questi passaggi è

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

dove si ltrova la funzione di confronto (dettagliata di seguito) ed transpose.map lesegue la metà delle fasi di confronto e trasposizione. (.)>>=idesegue il suo argomento due volte, essendo la forma senza punti di \f -> f.fe di un byte più breve in questo caso a causa delle regole di precedenza dell'operatore.

lè definito nella riga sopra come l x=z(!)(z(!)x(0:x))$tail x++[0]. Questo codice esegue un operatore di confronto (!)(vedi sotto) su ogni cella con prima il suo vicino sinistro, e poi con il suo vicino destro, comprimendo l'elenco xcon l'elenco spostato a destra 0:xe l'elenco spostato a sinistra tail x++[0]a sua volta. Usiamo gli zero per riempire gli elenchi spostati, poiché non possono mai verificarsi nella matrice preelaborata.

a!bè definito nella riga sopra questo come a!b=div(max(a*a)(a*b))a. Ciò che vogliamo fare qui è la seguente distinzione tra i casi:

  • Se sgn(a) = -sgn(b)abbiamo due aree opposte nella matrice e non desideriamo unificarle, quindi arimane invariata
  • Se sgn(b) = 0, abbiamo la custodia ad angolo in cui bè imbottitura e quindi arimane invariata
  • Se sgn(a) = sgn(b), desideriamo unificare le due aree e prendere quella con il valore assoluto più grande (per comodità).

Nota che sgn(a)non può mai essere 0. Lo realizziamo con la formula fornita. Se i segni di ae bdifferiscono, a*bè minore o uguale a zero, mentre a*aè sempre maggiore di zero, quindi lo scegliamo come massimo e dividiamo con aper tornare indietro a. Altrimenti, max(a*a)(a*b)è abs(a)*max(abs(a),(abs(b)), e dividendolo per a, otteniamo sgn(a)*max(abs(a),abs(b)), che è il numero con il valore assoluto più grande.

Per iterare la funzione ((.)>>=id$transpose.map l)fino a quando non raggiunge un punto fisso, usiamo (until=<<((==)=<<)), che è preso da questa risposta di StackOverflow .

Post produzione

Per la postelaborazione, utilizziamo la parte

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

che è solo una raccolta di passaggi.

(>>=id) comprime l'elenco degli elenchi in un unico elenco, nub elimina i doppi, (\x->length.($x).filter<$>[(>0),(<0)])suddivide l'elenco in una coppia di elenchi, uno per i numeri positivi e uno per i numeri negativi, e calcola le loro lunghezze.


2

Java 10, 359 355 281 280 261 246 byte

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 byte grazie a @NahuelFouilleul .

Provalo online.

Spiegazione:

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

1
-74 byte , rimuovendo il clone e usando |=2: 0 -> 2 e 1 -> 3, tuttavia è >0stato modificato in==1
Nahuel Fouilleul

scusate ho dovuto rimuovere i test in modo che il link tio si inserisse nei commenti
Nahuel Fouilleul

@NahuelFouilleul Grazie, utilizzo intelligente |=2! E potrei ancora usare <2invece che ==1per -1 byte controllando prima per 0(e quindi sono cambiati in 2, e poi usando il <2per verificare 1(che sono cambiati in 3).
Kevin Cruijssen

2

Python 3 , 167 byte

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)

Provalo online!


Python 2 , 168 byte

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

Provalo online!

-2 byte grazie a Kevin Cruijssen

+2 byte correzione della formattazione

Spiegazione

Un contatore viene mantenuto per 0 secondi e 1 secondo. Per ogni voce nella matrice, vengono eseguite le seguenti azioni:

  • Incrase counter per il valore corrente di 1
  • Se lo stesso valore esiste direttamente sopra o a sinistra, diminuisci di 1

Ciò si traduce in un falso positivo per casi allineati a sinistra come

0 0 1
1 1 1

o

0 1
1 1

Se si verifica una situazione del genere, il contatore viene diminuito di 1.

Il valore di ritorno è [#1, #0]


1
Temo che l'OP menzionato nel secondo commento dovrebbe essere l'ordine [#1, #0]. Imo un po 'inutile per far valere questo, ma è quello che è per ora. In ogni caso, si può golf la {not c}a {c^1}, e risolvere il problema che ho citato, modificando n[c]+=ad n[c^1]+=in una questione analoga. Bella risposta però, +1 da parte mia. :)
Kevin Cruijssen,

Ah, hai ragione. Grazie!
Jitse,

1

Perl 5 ( -0777p), 110 byte

Può essere migliorato, usa un regex per sostituirlo 1con 3, quindi 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


1

Gelatina , 44 36 byte

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

Provalo online!

Un collegamento monadico che accetta un elenco di elenchi di numeri interi come argomento e restituisce un elenco del numero di isole 1 e 0 in quell'ordine.

Spiegazione

Passo 1

Genera un elenco di tutti gli indici matrice ciascuno con gli indici del suo vicino a destra (se non sul lato destro) e verso il basso (se non in fondo)

Œ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

Dividi questi indici in base alla presenza di 1 o 0 nell'input. Restituisce un elenco di indici con vicini per 1 e un altro per 0.

  Ƈþ   | 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

Passaggio 3

Unisci elenchi con membri in comune e conteggi di output

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

1

T-SQL 2008, 178 byte

L'input è una variabile di tabella.

xey sono le coordinate

v è i valori 0 e 1 (potrebbe anche gestire altri valori numerici)

I dati di test utilizzati in questo esempio:

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

Provalo online


1

R , 194 172 byte

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

Provalo online!

Esegui una ricerca approfondita partendo da ogni cella della matrice uguale a 1 (o zero).

  • -2 byte grazie a @Giuseppe
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.