Найти острова 1 и 0 в матрице

29

Дана двумерная матрица из 0 и 1 с. Найдите количество островков для 1 и 0, где соседи находятся только по горизонтали и вертикали.

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
Вы должны добавить [[1,0];[0,1]]
тестовый пример,
8
Я бы предположил, что выходные данные могут быть в любом порядке, если указан порядок - он не добавляет никакого значения для форсирования заказа
streetst
8
Добро пожаловать на сайт!
Арно
1
Ответ в комментариях должен быть уточнен в основной части задачи. А точнее, если вы действительно хотите, чтобы мы возвращали 1 до 0, это должно быть четко указано.
Арно
4
Предлагаемый тестовый кейс: 11111 / 10001 / 10101 / 10001 / 111112 1
Кевин Круйссен

Ответы:

16

APL (Dyalog Unicode) , 29 28 байтов SBCS

-1 благодаря @ Adám

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

Попробуйте онлайн!

⊂,~∘⊂ матрица и ее отрицание

{ для каждого из них сделать

⍸⍵ список пар координат 1с

+/↑|∘.-⍨ матрица манхэттенских расстояний

2> матрица соседей

∨.∧⍨⍣≡ переходное закрытие

≢∪ количество уникальных строк

СПП
источник
это действительно умно Не могли бы вы пояснить, почему гарантированно работает последняя строка, т. е. почему уникальные строки эквивалентны ответу. Кроме того, "транзитивное закрытие", как у J ^:_?
Иона
1
@Jonah посмотри чат
нгн
16

J , 57 байт

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

Попробуйте онлайн!

Это одна из тех, где идея невероятно проста (и я думаю, что это весело), ​​но выполнение ее имело некоторую механическую длительность, которая маскирует простоту ... например, смещение исходной матрицы во всех направлениях с 0 заливкой является многословным ((,-)#:i.3) |.!.0 .

Вполне вероятно, что эту механическую длину можно продолжить, и я могу попробовать завтра вечером, но сейчас я опишу суть.

Скажите, что наш вклад:

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

Начнем с матрицы уникальных целых чисел одинакового размера:

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

Затем для каждой ячейки мы находим максимум всех ее соседей и умножаем на входную маску:

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

Мы повторяем этот процесс, пока матрица не перестанет меняться:

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

А затем посчитайте количество уникальных ненулевых элементов. Это говорит нам о количестве 1 островов.

Мы применяем тот же процесс к «1 минус вход», чтобы получить число 0-островков.

Ион
источник
3
Это очень похоже на механизм «заливки», действительно аккуратный.
Матье М.
7

JavaScript (ES7),  138 ... 107  106 байт

Возвращает массив [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

Попробуйте онлайн!

Как?

01с[0]с[1]2 .

Для сохранения байтов один и тот же код используется как для корневой итерации, так и для рекурсивных итераций, но он ведет себя немного по-разному.

Во время первой итерации:

  • Взнак равно0,5В-v0vзнак равно0vзнак равно1
  • ИксY(Икс-Икс)2+(Y-Y)2(Икс,Y)

Во время рекурсивных итераций:

  • с2c[v ^ 1]++с

комментарии

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
источник
Этот код не работает для больших матриц, таких как 100 * 100, только с 1 или 0 из-за переполнения стека.
КБ радости
3
@KBjoy Если в вызове явно не указано иное, наше правило по умолчанию состоит в том, что мы не заботимся об ограничениях реализации, пока основной алгоритм работает теоретически для любого ввода. ( Вот мета пост об этом, но, возможно, где-то есть более актуальный.)
Арно
7

MATL , 14 12 байт

,G@-K&1ZIugs

Попробуйте онлайн! Или проверьте все тестовые случаи .

объяснение

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

К (нгн / к) , 60 55 51 50 46 байт

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

Попробуйте онлайн!

~:\ пара входных данных и их отрицание (буквально: negate iterate-сходятся)

{ }' для каждого

,/x сгладить аргумент

&где 1с? - список показателей

(0,#*x)\ divmod width (входная), чтобы получить два отдельных списка для ys и xs

x-\:'x: расстояния на ось ∆x и ∆y

x*x: возведи их в квадрат

+/ добавить ∆x² и ∆y²

2> матрица соседей

{|/'x*\:x}/ переходное закрытие

#? считать уникальные строки

СПП
источник
Увидев ваш ответ, я рад, что не пытался заняться этим вопросом в K :)
streetst
2
@streetster хаха, спасибо! это не тот эффект, который я намеревался :) я бы на самом деле хотел бы побудить людей учиться (на любом диалекте) k и
играть
6

Wolfram Language (Mathematica) , 64 62 байта

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

Попробуйте онлайн!

Благодаря attinat : мы можем записать 1<0вместо Falseи сохранить два байта.

версия без гольфа:

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

Конечно, есть встроенная Mathematica,MorphologicalComponents которая принимает массив (или изображение) и возвращает его с заменой пикселей каждого морфологически связанного острова на индекс острова. Принятие Maxэтого результата дает число островов (фоновые нули остаются равными нулю, а индекс островов начинается с 1). Нам нужно сделать это отдельно для массива (с указанием количества 1-островков) и одного минуса массива (с указанием количества 0-островков). Чтобы убедиться, что диагональные соседи не считаются соседями, необходимо указать эту опцию CornerNeighbors->False.

Римский
источник
-2 байта, поскольку неравенства имеют более высокий приоритет, чемRule
attinat
5

Python 3, 144 127 байт

Это решение использует cv2потрясающие возможности обработки изображений. Несмотря на менее удивительные, супер длинные и удобочитаемые имена методов, он превосходит оба других ответа 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))

Expanded:

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)
Даниил
источник
Я не слишком знаком с Python, но зачем вам нужны явные имена аргументов? Разве не 4вместо connectivity=4и n.uint8не dtype=n.uint8возможно?
Кевин Круйссен
@KevinCruijssen, вам нужны имена аргументов, если вы пропустите необязательные аргументы. Взглянув на документы, мне на самом деле не нужно пропускать, что экономит мне много байтов. Благодарность!
Даниэль
Ах, хорошо, я подумал, что это что-то подобное, но когда я просто посмотрел на документы, я смог найти только один cv2.connectedComponentsметод, поэтому я был озадачен и подумал, что, возможно, была другая причина для необходимости имен аргументов. Как я уже сказал, я не слишком знаком с Python. Все, что я узнал от этого, отсюда на CCGC. ;) Но имеет смысл использовать имена переменных, чтобы пропустить другие необязательные аргументы.
Кевин Круйссен
1
Очень хорошо! Я нашел онлайн компилятор, который включает в себя модуль cv2 здесь .
Джитс
5

J , 46 44 43 байт

-1 байт благодаря @miles

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

Попробуйте онлайн!

тесты и ,& -.обертка, украденная из ответа @ jonah

,& -. для ввода и его отрицания делаем:

4$.$. (y, x) координаты единиц как матрицы n × 2

1#.[:|@-"1/~ Манхэттенские расстояния: abs (∆x) + abs (∆y)

2> матрица соседей

[:+./ .*~^:_: переходное закрытие

#&~.&( ) количество уникальных строк

СПП
источник
1
Вы можете составить длину и уникальность, чтобы сохранить еще один байт, т.е. ,&#&~.чтобы избежать ограничения[:
миль
@ Майлс спасибо
нгн
3

Сетчатка 0.8.2 , 155 байт

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

Попробуйте онлайн! Ссылка включает в себя тестовый пример. Объяснение:

s`1(.*)
;$1a

Если есть 1, измените его на ;и добавьте aв конец ввода, чтобы он не мешал.

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

Наводнение залейте больше соседних 1s с ;s.

}

Повторяйте, пока все острова 1s не были превращены в ;s.

s`0(.*)
:$1b

Если есть 0, измените его на :и добавьте bк концу ввода, чтобы он не мешал.

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

Наводнение залейте больше соседних 0s с :s.

}

Повторяйте, пока все острова 0s не были превращены в :s.

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

Отдельно посчитайте количество островов 1s и 0s.

Нил
источник
3

Haskell , 228 227 225 224 байта

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

Попробуйте онлайн!

Объяснение:

Идея этого решения заключается в следующем: инициализировать матрицу с уникальными значениями в каждой ячейке, положительными для 1и отрицательными для 0. Затем несколько раз сравнивайте каждую ячейку с ее соседями и, если сосед имеет тот же знак, но число с большим абсолютным значением, замените номер ячейки на номер соседа. Как только это достигнет фиксированной точки, подсчитайте количество различных положительных чисел для количества 1регионов и различных отрицательных чисел для количества 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..]

можно разделить на предварительную обработку (присвоение номеров ячейкам), итерацию и постобработку (подсчет ячеек)

предварительная обработка

Часть предварительной обработки является функцией

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

Который использует zкак сокращение для того, zipWithчтобы сбрить несколько байтов. То, что мы здесь делаем, это сжатие двумерного массива с целочисленными индексами в строках и нечетными целочисленными индексами в столбцах. Мы делаем это, так как мы можем построить уникальное целое число из пары целых чисел, (i,j)используя формулу (2^i)*(2j+1). Если мы генерируем только нечетные целые числа для j, мы можем пропустить вычисление 2*j+1, сохранив три байта.

С уникальным числом нам теперь нужно только умножить на знак, основанный на значении в матрице, которое получается как 2*x-1

итерация

Итерация выполняется

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

Поскольку входные данные представлены в виде списка списков, мы выполняем сравнение соседей в каждой строке, транспонируем матрицу, снова выполняем сравнение в каждой строке (что из-за транспонирования является тем, что было в столбцах ранее) и снова транспонируем. Код, который выполняет один из этих шагов:

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

где l- функция сравнения (подробно описано ниже), которая transpose.map lвыполняет половину шагов сравнения и транспонирования. (.)>>=idвыполняет свой аргумент дважды, будучи бессмысленной формой \f -> f.fи на один байт короче в этом случае из-за правил приоритета оператора.

lопределяется в строке выше как l x=z(!)(z(!)x(0:x))$tail x++[0]. Этот код выполняет оператор сравнения (!)(см. Ниже) для каждой ячейки, в которой сначала находится ее левый сосед, а затем - его правый сосед, путем сжатия списка по очереди xсо сдвинутым вправо списком 0:xи левым сдвинутым списком tail x++[0]. Мы используем нули для заполнения сдвинутых списков, поскольку они никогда не могут появляться в предварительно обработанной матрице.

a!bопределяется в строке выше этого как a!b=div(max(a*a)(a*b))a. То, что мы хотим сделать здесь, это следующее различие в регистре:

  • Если sgn(a) = -sgn(b)у нас есть две противоположные области в матрице и мы не хотим их объединять, то есть aостается неизменным
  • Если sgn(b) = 0у нас есть угловой случай, где bнаходится отступ, и, следовательно, aостается неизменным
  • Если sgn(a) = sgn(b)мы хотим объединить две области и взять одну с большим абсолютным значением (для удобства).

Обратите внимание, что sgn(a)никогда не может быть 0. Мы осуществляем это с помощью приведенной формулы. Если знаки aи bотличаются, a*bменьше или равно нулю, а a*aвсегда больше нуля, поэтому мы выбираем его как максимум и делим aна, чтобы вернуться a. Иначе, max(a*a)(a*b)есть abs(a)*max(abs(a),(abs(b)), и, деля это на a, мы получаем sgn(a)*max(abs(a),abs(b)), который является числом с большим абсолютным значением.

Для итерации функции, ((.)>>=id$transpose.map l)пока она не достигнет фиксированной точки, мы используем (until=<<((==)=<<)), что взято из этого ответа stackoverflow .

Постобработка

Для постобработки мы используем часть

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

которая является просто набором шагов.

(>>=id)объединяет список списков в один список, nubизбавляется от двойников, (\x->length.($x).filter<$>[(>0),(<0)])разбивает список на пару списков, один для положительных и один для отрицательных чисел, и вычисляет их длины.

Sacchan
источник
2

Java 10, 359 355 281 280 261 246 байт

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 байта благодаря @NahuelFouilleul .

Попробуйте онлайн.

Объяснение:

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 байта , удаляя клон и используя |=2: 0 -> 2 и 1 -> 3, однако >0был изменен на==1
Науэль Фуйе
извините, мне пришлось удалить тесты, чтобы ссылка tio помещалась в комментариях
Науэль Фуйе
@NahuelFouilleul Спасибо, умное использование |=2! И я все еще мог бы использовать <2вместо ==1-1 байт, сначала проверив наличие 0(и, таким образом, они были изменены на 2, а затем используя <2для проверки 1(которые были изменены 3).
Кевин Круйссен
2

Python 3 , 167 байт

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)

Попробуйте онлайн!


Python 2 , 168 байт

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

Попробуйте онлайн!

-2 байта благодаря Кевину Круйссену

Исправление форматирования +2 байта

объяснение

Счетчик сохраняется на 0 и 1. Для каждой записи в матрице выполняются следующие действия:

  • Включить счетчик для текущего значения на 1
  • Если то же значение существует непосредственно над или слева, уменьшите на 1

Это приводит к ложному срабатыванию для выровненных по левому краю случаев, таких как

0 0 1
1 1 1

или

0 1
1 1

Если возникает такая ситуация, счетчик уменьшается на 1.

Возвращаемое значение [#1, #0]

Джитсе
источник
1
Я боюсь, что ОП, упомянутый во втором комментарии, порядок должен быть [#1, #0]. Немного бессмысленно имо, чтобы навязывать это, но это то, что есть сейчас. Во всяком случае, вы можете Гольф {not c}в {c^1}, и исправить эту проблему , я уже упоминал, изменив n[c]+=к n[c^1]+=подобному вопросу. Хороший ответ, хотя +1 от меня. :)
Кевин Круйссен
Ах, ты прав. Благодарность!
Джитс
1

Perl 5 ( -0777p), 110 байт

Может быть улучшено, используется регулярное выражение для замены 1на 3, затем 0на 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

Желе , 44 36 байт

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

Попробуйте онлайн!

Монадическая ссылка, принимающая список списков целых чисел в качестве аргумента и возвращающая список из числа островков 1 и 0 в указанном порядке.

объяснение

Шаг 1

Создайте список всех матричных индексов, каждый с индексами соседа справа (если не справа) и вниз (если не снизу)

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

Шаг 2

Разделите эти индексы по тому, был ли 1 или 0 на входе. Возвращает один список индексов с соседями для 1 с, а другой для 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

Шаг 3

Объединение списков с общими членами и выходным количеством

           ƲÐ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 байт

Ввод является табличной переменной.

х и у координаты

v это значения 0 и 1 (также может обрабатывать другие числовые значения)

Тестовые данные, используемые в этом примере:

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

Попробуйте онлайн

t-clausen.dk
источник
1

R , 194 172 байт

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

Попробуйте онлайн!

Выполните поиск в глубину, начиная с каждой ячейки матрицы, равной 1 (или нулю).

  • -2 байта благодаря @Giuseppe
digEmAll
источник