행렬에서 1과 0의 섬을 찾으려면


29

0과 1의 2 차원 행렬이 주어집니다. 이웃이 가로 및 세로로만있는 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]]대각선 연결이 포함되지 않도록 테스트 케이스를 추가해야합니다
Sanchises

8
주문이 지정되어있는 한 출력이 어느 순서
로나

8
사이트에 오신 것을 환영합니다!
Arnauld

1
의견에 답변 된 내용은 도전의 본문에서 명확히해야합니다. 더 구체적으로 말하면, 우리가 실제로 0보다 1을 반환하기를 원한다면 분명히 명시해야합니다.
Arnauld

4
권장 테스트 사례 : 11111 / 10001 / 10101 / 10001 / 111112 1
Kevin Cruijssen

답변:


16

APL (Dyalog Unicode) , 29 28 바이트 SBCS

@ Adám 덕분에 -1

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

온라인으로 사용해보십시오!

⊂,~∘⊂ 매트릭스와 그 부정

{ 그들 각자를 위해

⍸⍵ 1의 좌표 쌍 목록

+/↑|∘.-⍨ 맨해튼 거리의 행렬

2> 인접 행렬

∨.∧⍨⍣≡ 전이 폐쇄

≢∪ 고유 한 행 수


이것은 정말 영리합니다. 최종 행이 작동하는 이유, 즉 고유 행이 답과 같은 이유를 자세히 설명 할 수 있습니다. 또한, "전이 폐쇄"는 J와 비슷 ^:_합니까?
요나

1
@Jonah 볼 채팅
NGN

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

그런 다음 0이 아닌 고유 한 요소의 수를 계산하십시오. 그것은 우리에게 1 섬의 수를 알려줍니다.

동일한 프로세스를 "1에서 입력을 뺀 값"에 적용하여 0 섬 수를 얻습니다.


3
이것은 "플러드 필 (flood-fill)"매커니즘과 매우 흡사 해 보입니다.
Matthieu M.

7

자바 스크립트 (ES7),  138 ...  107106 바이트

배열을 반환합니다 [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

온라인으로 사용해보십시오!

방법?

우리는 재귀 함수를 사용합니다. 초기 호출 중에 과 찾습니다 . 이러한 시작점을 찾을 때마다 해당 섬 카운터 ( 또는 )를 증가시키고 재귀 단계로 들어가서 유사한 인접 셀의 영역을 로 채 웁니다 .01c[0]c[1]2

바이트를 절약하기 위해 루트 반복과 재귀 반복에 모두 동일한 코드가 사용되지만 약간 다르게 동작합니다.

첫 번째 반복 중 :

  • 우리는 시작 정도로 반올림됩니다 모두 과 비트 OR에, 감사합니다.V=0.5Vv0v=0v=1
  • X 와 는 정의되어 있지 않으며 계산 된 사분면 는 NaN으로 평가됩니다 . 값에 관계없이 부등식 테스트가 실패하도록합니다 .Y(xX)2+(yY)2 ( x , y )(x,y)

재귀 반복 중에 :

  • 매개 변수 는 배열 대신 정수 ( )로 설정됩니다 . 숫자는 JS의 객체이므로 가 숫자 인 경우 표현식 은 유효 하지만 전혀 효과가 없습니다. 즉, 현재 출발점을 찾고 있는지 또는 홍수로 채울지 여부를 알지 않고도이 문을 무조건 실행할 수 있습니다.c2cc[v ^ 1]++c

댓글

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

이 코드는 스택 오버플로로 인해 1 또는 0으로 100 * 100과 같은 큰 행렬에는 작동하지 않습니다.
KB 기쁨

3
@KBjoy 챌린지에서 달리 명시 적으로 지정하지 않는 한 기본 규칙은 기본 알고리즘이 입력에 대해 이론적으로 작동하는 한 구현 제한에 신경 쓰지 않는 것입니다. ( 여기에 메타 게시물이 있지만 어딘가에 더 관련있는 게시물 이있을 수 있습니다.)
Arnauld

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

K (ngn / k) , 60 55 51 50 46 바이트

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

온라인으로 사용해보십시오!

~:\ 입력과 그것의 부정의 쌍 (문자 적으로 : 반복 수렴을 부정)

{ }' 각각

,/x 인수를 평평하게하다

&1은 어디에 있습니까? -지수 목록

(0,#*x)\ ys와 xs에 대한 두 개의 별도 목록을 얻는 divmod width (input)

x-\:'x: 축당 거리 ∆x 및 ∆y

x*x: 그들을 제곱

+/ ∆x² 및 ∆y² 추가

2> 인접 행렬

{|/'x*\:x}/ 전이 폐쇄

#? 고유 한 행 개수


귀하의 답변을 본 후 K에서이 문제를 해결하려고하지 않았기 때문에 기쁩니다.
streetster

2
@streetster haha, 감사합니다! 그것은 내가 의도 한 효과가 아닙니다. :) 실제로 사람들이 k와 골프를 배울 수 있도록 격려하고 싶습니다
ngn

6

Wolfram Language (Mathematica) , 64 62 바이트

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

온라인으로 사용해보십시오!

attinat 덕분에 : 우리는 1<0대신 False2 바이트를 쓰고 저장할 수 있습니다 .

골프 용 버전 :

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

물론 배열 (또는 이미지)을 취하고 형태 적으로 연결된 각 섬의 픽셀을 섬 인덱스로 대체하여 반환 하는 Mathematica 내장 MorphologicalComponents이 있습니다. Max이 결과를 취하면 섬 수가 나타납니다 (배경 0은 0으로 남고 섬 인덱스는 1에서 시작 함). 우리는 배열 (1 섬 수를 제공)과 하나 빼기 (0 섬 수를 제공)에 대해 별도로이 작업을 수행해야합니다. 대각선 이웃이 이웃으로 간주되지 않도록하려면 옵션을 제공 CornerNeighbors->False해야합니다.


-2 바이트 불평등은보다 높은 우선 순위를 갖고 있기 때문에Rule
attinat

5

파이썬 3, 144127 바이트

이 솔루션은 cv2놀라운 이미지 처리 능력을 사용합니다. cv의 덜 멋지고 길고 읽을 수있는 메소드 이름에도 불구하고 다른 Python 답변보다 뛰어납니다!

골프 :

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

넓히는:

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)

나는 파이썬에 익숙하지 않지만 왜 명시적인 인수 이름이 필요한가? 그냥가 4대신 connectivity=4하고 n.uint8대신 dtype=n.uint8가능?
Kevin Cruijssen

@KevinCruijssen, 선택적 인수를 건너 뛰면 인수 이름이 필요합니다. 문서를 들여다 보면 실제로 건너 뛸 필요가 없으므로 많은 바이트가 절약됩니다. 감사!
다니엘

아, 좋아, 나는 그것이 그런 것이라고 생각했지만 방금 문서를 볼 때 단일 cv2.connectedComponents방법 만 찾을 수 있었기 때문에 혼란스럽고 인수 이름이 필요한 다른 이유가 있다고 생각했습니다. 내가 말했듯이, 나는 파이썬에 너무 익숙하지 않다. 내가 배운 것은 CCGC에 관한 것입니다. ;) 그러나 변수 이름을 사용하여 다른 선택적 인수를 건너 뛰는 것이 좋습니다.
Kevin Cruijssen

1
아주 좋아요! 여기 cv2 모듈을 포함하는 온라인 컴파일러를 찾았 습니다 .
Jitse

5

J , 46 44 43 바이트

@ 마일 덕분에 -1 바이트

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

온라인으로 사용해보십시오!

@ jonah의 답변,& -. 에서 도난당한 테스트 및 래퍼

,& -. 입력과 그 부정을 위해 :

4$.$. n × 2 행렬로 1의 (y, x) 좌표

1#.[:|@-"1/~ 맨해튼 거리 : abs (∆x) + abs (∆y)

2> 인접 행렬

[:+./ .*~^:_: 전이 폐쇄

#&~.&( ) 고유 한 행 수


1
당신은 길이를 구성 할 수 있으며, 다른 바이트를 저장 독특한, 즉 ,&#&~.캡 피하기 위해[:
마일을

@ 마일즈 감사합니다
ngn

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;

홍수는 더 이상 인접 채우기 1로들 ;들.

}

의 모든 섬 1이로 바뀔 때까지 반복 ;합니다.

s`0(.*)
:$1b

가있는 경우로 0변경 하고 입력 끝에 :a b를 추가 하여 방해가되지 않도록하십시오.

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

홍수는 더 이상 인접 채우기 0로들 :들.

}

의 모든 섬 0이로 바뀔 때까지 반복 :합니다.

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

1s 및 0s 의 섬 수를 별도로 계산하십시오 .


3

하스켈 , 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합니다. 여기서 우리는 행에 정수 인덱스와 열에 홀수 정수 인덱스가있는 2 차원 배열을 압축합니다. 우리는 (i,j)공식을 사용하여 정수 쌍으로부터 고유 한 정수를 만들 수 있기 때문에 이렇게 합니다 (2^i)*(2j+1). 에 대해 홀수 정수만 생성하면 3 바이트를 절약 j하면서을 계산하는 것을 건너 뛸 수 있습니다 2*j+1.

고유 번호를 사용하면 이제 행렬의 값을 기반으로 부호 만 곱하면됩니다. 2*x-1

되풀이

반복은 다음과 같이 수행됩니다.

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

입력은리스트리스트의 형태이기 때문에, 우리는 각 행에서 이웃 비교를 수행하고, 행렬을 전치하고, 각 행에서 다시 비교를 수행합니다 (조치로 인해 이전의 열이었던 것입니다). 이 단계 중 하나를 수행하는 코드는

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

여기서 l비교 기능 (아래에 자세히 설명되어 있음) transpose.map l은 비교 및 ​​조옮김 단계의 절반을 수행합니다. 이 경우, 연산자 우선 순위 규칙으로 인해 (.)>>=id포인트없는 형태이며 \f -> f.f1 바이트 더 짧은 인수를 두 번 수행합니다 .

l위의 행에서으로 정의됩니다 l x=z(!)(z(!)x(0:x))$tail x++[0]. 이 코드 (!)는 목록 x을 오른쪽으로 이동 한 목록 0:x과 왼쪽으로 이동 한 목록 tail x++[0]으로 차례로 압축하여 모든 셀에 대해 비교 연산자 (아래 참조)를 수행합니다 . 사전 처리 된 행렬에서는 절대로 이동할 수 없으므로 이동 된 목록을 채우는 데 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*a0보다 항상 더 큰 우리가 가진 최대 격차로 선택할 수 있도록, a다시 얻을 a. 그렇지 않으면 max(a*a)(a*b)is abs(a)*max(abs(a),(abs(b))이고 이것을로 나눔으로써 절대 값이 더 큰 숫자 인을 a얻습니다 sgn(a)*max(abs(a),abs(b)).

((.)>>=id$transpose.map l)고정 점에 도달 할 때까지 함수를 반복하기 위해이 stackoverflow answer(until=<<((==)=<<)) 에서 가져온을 사용 합니다 .

후 처리

후 처리를 위해 부품을 사용합니다

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

단계의 모음 일뿐입니다.

(>>=id)리스트리스트를 단일리스트로 스쿼시하고, nub복식을 제거 (\x->length.($x).filter<$>[(>0),(<0)])하고,리스트를 한 쌍의리스트로 분할하고 (양을위한 것, 음을위한 것), 길이를 계산합니다.


2

자바 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;}}

@NahuelFouilleul 덕분에 -74 바이트 .

온라인으로 사용해보십시오.

설명:

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
Nahuel Fouilleul

죄송합니다. tio 링크가 댓글에 맞도록 테스트를 제거해야했습니다
Nahuel Fouilleul

@NahuelFouilleul 감사합니다, 똑똑한 사용 |=2! 그리고 먼저 -1 바이트 <2대신 ==1에 먼저 검사하여 0(로 변경 2한 다음 <2로 검사하여 1(로 변경됨 3) 검사 할 수 있음 )
Kevin Cruijssen

2

파이썬 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)

온라인으로 사용해보십시오!


파이썬 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

온라인으로 사용해보십시오!

Kevin Cruijssen 덕분에 -2 바이트

+2 바이트 형식 수정

설명

카운터는 0과 1로 유지됩니다. 행렬의 각 항목에 대해 다음 작업이 수행됩니다.

  • 현재 가치에 대한 Incrase 카운터 1
  • 동일한 값이 바로 위 또는 왼쪽에 존재하면 1 씩 감소

결과적으로 왼쪽 정렬 된 경우에 대해 오탐 (false positive)

0 0 1
1 1 1

또는

0 1
1 1

이러한 상황이 발생하면 카운터는 1 씩 줄어 듭니다.

반환 값은 [#1, #0]


1
나는 두 번째 의견에 언급 된 OP가 명령이 있어야한다고 두려워합니다 [#1, #0]. 이것을 시행하기 위해 무의미한 imo이지만 지금은 그것이 그렇습니다. 어쨌든 {not c}to를 골프화하고 비슷한 문제 {c^1}로 변경 n[c]+=하여 언급 한 문제를 해결할 수 있습니다 n[c^1]+=. 그래도 좋은 대답은 +1입니다. :)
Kevin Cruijssen

아 맞아. 감사!
Jitse

1

펄 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 바이트

입력은 테이블 변수입니다.

x와 y는 좌표입니다

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

온라인으로 사용해보십시오


1

R , 194172 바이트

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 (또는 0) 인 행렬의 각 셀에서 시작하여 깊이 우선 검색을 수행하십시오.

  • @Giuseppe 덕분에 -2 바이트
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.