행렬의 0이 아닌 요소가 모두 연결되어 있는지 확인


19

입력:

[0-9] 범위의 정수를 포함하는 행렬 입니다.

도전:

0이 아닌 모든 요소가 서로 수직 및 / 또는 수평으로 연결되어 있는지 확인하십시오.

산출:

truthy 값 모두가 연결되어있는 경우와 falsy 값이 비 - 제로 엘리먼트 / 다른 요소 / 그룹에 연결되지 않은 그룹이있는 경우.

테스트 사례 :

테스트 사례는 라인별로 구분됩니다. 테스트 케이스는 더 편리한 형식으로 볼 수 있습니다 여기에 ( 다다 했네 ).

다음은 모두 연결되어 있으며 진실한 값을 반환해야합니다.

0
--- 
0 0
---
1 1 1
0 0 0
---
1 0 0
1 1 1
0 0 1
---
0 0 0 0 0 0
0 0 3 5 1 0
0 1 0 2 0 1
1 1 0 3 1 6
7 2 0 0 3 0
0 8 2 6 2 9
0 0 0 0 0 5

다음은 모두 연결되어 있지 않으며 잘못된 값을 반환해야합니다.

0 1
1 0
---
1 1 1 0
0 0 0 2
0 0 0 5
---
0 0 5 2
1 2 0 0
5 3 2 1
5 7 3 2
---
1 2 3 0 0 5
1 5 3 0 1 1
9 0 0 4 2 1
9 9 9 0 1 4
0 1 0 1 0 0

이것은 이므로 각 언어에서 가장 짧은 제출이 이깁니다. 설명이 권장됩니다!


이 도전에서 영감을 얻었습니다 .


아마도 입력에는 반드시 1과 0 (또는 진리와 거짓) 만 포함되어야합니다. 이는 본질적으로 연결된 컴포넌트에 관한 것입니다.
NikoNyrh

입력을 1d 배열과 여러 열로 취할 수 있습니까?
ovs

확실히 @ov. 나는 그것이 이미 대답 한 다른 사람들에 비해 어떤 이점을 제공해야한다는 것을 알 수 없습니다.
Stewie Griffin

2
관련 : 0이 아닌 모든 요소를 ​​연결하기 위해 얼마나 많은 0을 변경해야합니까?
dylnan

관련 : 구성 요소의 수를 계산합니다 (그러나 대각선 항목이 인접 해 있음).
Misha Lavrov

답변:


9

레티 나 0.8.2 , 80 77 바이트

T`d`@1
1`1
_
+m`^((.)*)(1|_)( |.*¶(?<-2>.)*(?(2)(?!)))(?!\3)[1_]
$1_$4_
^\D+$

온라인으로 사용해보십시오! 편집 : @FryAmTheEggman 덕분에 1 바이트가 절약되었습니다. 설명:

T`d`@1

@s와 1s 의 배열로 단순화합니다 .

1`1
_

하나 1를로 변경하십시오 _.

+m`^((.)*)(1|_)( |.*¶(?<-2>.)*(?(2)(?!)))(?!\3)[1_]
$1_$4_

에서 _인접 1s 까지 홍수 채우기 .

^\D+$

1s가 남아 있는지 테스트하십시오 .


@FryAmTheEggman 감사합니다. 또 다른 2 바이트를 저장하는 방법에 대한 아이디어를 주셨습니다.
Neil

7

자바 스크립트 (ES6) 136 135 바이트

부울을 반환합니다.

m=>!/[1-9]/.test((g=(y,x=0)=>1/(n=(m[y]||0)[x])&&!z|n?(m[y++][x]=0,z=n)?g(y,x)&g(--y-1,x)&g(y,x+1)||g(y,x-1):g(m[y]?y:+!++x,x):m)(z=0))

테스트 사례

댓글

재귀 함수 g ()는 먼저 (전역 적으로 정의 된 플래그 z0 으로 설정되어있는 한) 0 이 아닌 셀을 찾은 다음 ( z! = 0이 되 자마자) 플러드 필링을 시작합니다 .

m =>                               // given the input matrix m
  !/[1-9]/.test((                  // test whether there's still a non-zero digit
    g = (y, x = 0) =>              //   after recursive calls to g(), starting at (x=0,y=0):
      1 / (n = (m[y] || 0)[x]) &&  //     n = current cell; if it is defined:
      !z | n ? (                   //       if z is zero or n is non-zero:
          m[y++][x] = 0,           //         we set the current cell to zero
          z = n                    //         we set z to the current cell
        ) ?                        //         if z is non-zero:
          g(y, x) &                //           flood-fill towards bottom
          g(--y - 1, x) &          //           flood-fill towards top
          g(y, x + 1) ||           //           flood-fill towards right
          g(y, x - 1)              //           flood-fill towards left
        :                          //         else:
          g(m[y] ? y : +!++x, x)   //           look for a non-zero cell to start from
      :                            //       else:
        m                          //         return the matrix
    )(z = 0)                       //   initial call to g() + initialization of z
  )                                // end of test()

7

MATL , 7 바이트

4&1ZI2<

이것은 모든 것을 진실한 출력으로 포함하는 행렬, 또는 거짓 을 적어도 0으로 포함하는 행렬을 제공합니다. 합니다. 온라인으로 사용해보십시오!

당신은 또한 추가 truthiness / falsiness을 확인할 수 있습니다 if- else바닥 글에서 지점; 시도해보십시오!

또는 모든 테스트 사례를 확인하십시오 .

설명

4       % Push 4 (defines neighbourhood)
&       % Alternative input/output specification for next function
1ZI     % bwlabeln with 2 input arguments: first is a matrix (implicit input),
        % second is a number (4). Nonzeros in the matrix are interpreted as
        % "active" pixels. The function gives a matrix of the same size
        % containing positive integer labels for the connected components in 
        % the input, considering 4-connectedness
2<      % Is each entry less than 2? (That would mean there is only one
        % connected component). Implicit display

1
OP의 메모 : 의심의 여지가있는 경우 : 출력이 완벽하고 링크 된 메타 포스트를 준수합니다.
Stewie Griffin

MATL / matlab은 숫자 배열이 0을 포함하지 않는 진실한 IFF라고 생각합니다. mathworks.com/help/matlab/ref/if.html (이전 코멘트 삭제)
Sparr

@Sparr (사실,이다 는 더 0을 포함하지 비어 있지 IFF에 내가 어떤 비어 있지 않은 배열이 다른 언어 truthy는 것을 알았을 때 나는 또한 혼란스러워했다.)
루이스 Mendo


4

C, 163 바이트

2 바이트를 절약 한 @ user202729에게 감사합니다!

*A,N,M;g(j){j>=0&j<N*M&&A[j]?A[j]=0,g(j+N),g(j%N?j-1:0),g(j-N),g(++j%N?j:0):0;}f(a,r,c)int*a;{A=a;N=c;M=r;for(c=r=a=0;c<N*M;A[c++]&&++r)A[c]&&!a++&&g(c);return!r;}

0이 아닌 첫 번째 요소를 찾을 때까지 행렬을 반복합니다. 그런 다음 잠시 동안 루프를 중지하고 찾은 요소에 연결된 모든 0이 아닌 요소를 재귀 적으로 설정합니다. 그런 다음 나머지 모든 행렬을 반복하여 모든 요소가 0인지 확인합니다.

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

풀림 :

*A, N, M;

g(j)
{
    j>=0 & j<N*M && A[j] ? A[j]=0, g(j+N), g(j%N ? j-1 : 0), g(j-N), g(++j%N ? j : 0) : 0;
}

f(a, r, c) int*a;
{
    A = a;
    N = c;
    M = r;

    for (c=r=a=0; c<N*M; A[c++] && ++r)
        A[c] && !a++ && g(c);

    return !r;
}

2

펄, 80 79 78 73 70 바이트

포함 +2을 위해0a

STDIN에 공백없이 입력 행렬을 제공하십시오 (또는 실제로 공백으로 분리 된 행으로)

perl -0aE 's%.%$".join"",map chop,@F%seg;s%\b}|/%z%;y%w-z,-9%v-~/%?redo:say!/}/'
000000
003510
010201
110316
720030
082629
000005
^D

파일에 넣으면 쉽게 읽을 수 있습니다.

#!/usr/bin/perl -0a
use 5.10.0;
s%.%$".join"",map chop,@F%seg;s%\b}|/%z%;y%w-z,-9%v-~/%?redo:say!/}/

1

자바 8, 226 바이트

m->{int c=0,i=m.length,j;for(;i-->0;)for(j=m[i].length;j-->0;)if(m[i][j]>0){c++;f(m,i,j);}return c<2;}void f(int[][]m,int x,int y){try{if(m[x][y]>0){m[x][y]=0;f(m,x+1,y);f(m,x,y+1);f(m,x-1,y);f(m,x,y-1);}}catch(Exception e){}}

꽤 오랜 시간이 걸렸으므로 지금 작동하고있어 기쁩니다 ..

설명:

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

m->{                   // Method with integer-matrix parameter and boolean return-type
  int c=0,             //  Amount of non-zero islands, starting at 0
      i=m.length,j;    //  Index integers
  for(;i-->0;)         //  Loop over the rows
    for(j=m[i].length;j-->0;)
                       //   Inner loop over the columns
      if(m[i][j]>0){   //    If the current cell is not 0:
        c++;           //     Increase the non-zero island counter by 1
        f(m,i,j);}     //     Separate method call to flood-fill the matrix
  return c<2;}         //  Return true if 0 or 1 islands are found, false otherwise

void f(int[][]m,int x,int y){
                        // Separated method with matrix and cell input and no return-type
  try{if(m[x][y]>0){    //  If the current cell is not 0:
    m[x][y]=0;          //   Set it to 0
    f(m,x+1,y);         //   Recursive call south
    f(m,x,y+1);         //   Recursive call east
    f(m,x-1,y);         //   Recursive call north
    f(m,x,y-1);}        //   Recursive call west
  }catch(Exception e){}}//  Catch and swallow any ArrayIndexOutOfBoundsExceptions
                        //  (shorter than manual if-checks)


1

젤리 , 23 바이트

FJṁa@µ«Ḋoµ€ZUµ4¡ÐLFQL<3

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


설명.

이 프로그램은 각 형태 학적 구성 요소에 다른 숫자를 표시 한 다음 3 개 미만의 숫자가 있는지 확인합니다. (포함0 ).

행렬의 행을 고려하십시오.

«Ḋo   Given [1,2,3,0,3,2,1], return [1,2,3,0,2,1,1].
«     Minimize this list (element-wise) and...
 Ḋ      its dequeue. (remove the first element)
      So min([1,2,3,0,3,2,1],
             [2,3,0,3,2,1]    (deque)
      ) =    [1,2,0,0,2,1,1].
  o   Logical or - if the current value is 0, get the value in the input.
         [1,2,0,0,2,1,1] (value)
      or [1,2,3,0,3,2,1] (input)
      =  [1,2,3,0,2,1,1]

이 함수를 행렬의 모든 행과 열에 반복적으로 적용하면 모든 형태 학적 구성 요소가 동일한 레이블을 갖게됩니다.

µ«Ḋoµ€ZUµ4¡ÐL  Given a matrix with all distinct elements (except 0),
               label two nonzero numbers the same if and only if they are in
               the same morphological component.
µ«Ḋoµ          Apply the function above...
     €           for ach row in the matrix.

      Z        Zip, transpose the matrix.
       U       Upend, reverse all rows in the matrix.
               Together, ZU rotates the matrix 90° clockwise.
         4¡    Repeat 4 times. (after rotating 90° 4 times the matrix is in the
               original orientation)
           ÐL  Repeat until fixed.

그리고 마지막으로...

FJṁa@ ... FQL<3   Main link.
F                 Flatten.
 J                Indices. Get `[1,2,3,4,...]`
  ṁ               old (reshape) the array of indices to have the same
                  shape as the input.
   a@             Logical AND, with the order swapped. The zeroes in the input
                  mask out the array of indices.
      ...         Do whatever I described above.
          F       Flatten again.
           Q      uniQue the list.
            L     the list of unique elements have Length...
             <3   less than 3.

선형 시간에 할 수 있다면 상상의 현상금입니다. 젤리에서는 불가능하다고 생각합니다. 심지어 ¦O (n) 도 걸립니다.
user202729

(파이썬 평가없이, 물론)
user202729

1

하스켈 , 132 바이트

 \m->null.snd.until(null.fst)(\(f,e)->partition(\(b,p)->any(==1)[(b-d)^2+(p-q)^2|(d,q)<-f])e).splitAt 1.filter((/=0).(m!)).indices$m

솔로 히토리 퍼즐 에서 추출

indices m(line,cell)입력 그리드 의 위치를 나열합니다 .

filter((/=0).(m!)) 0이 아닌 값으로 모든 위치를 필터링합니다.

splitAt 1 첫 번째 멤버를 나머지 목록 옆의 단일 목록으로 분할합니다.

any(==1)[(b-d)^2+(p-q)^2|(d,q)<-f](b,p)프론티어를 터치하면 알려줍니다 f.

\(f,e)->partition(\(b,p)->touches(b,p)f)e 아직 접촉하지 않은 접촉기에서 접촉기를 분리합니다.

until(null.fst)advanceFrontier 프론티어가 더 이상 전진 할 수 없을 때까지 이것을 반복합니다.

null.snd 도달 할 모든 위치가 실제로 도달했는지 결과를 확인합니다.

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


1

Grime , 37 바이트

C=[,0]&<e/\0{/e\0*0$e|CoF^0oX
e`C|:\0

1일치하고 일치 0하지 않는 인쇄 합니다 . 온라인으로 사용해보십시오!

설명

비 터미널 C은 영어 읽기 순서에서 행렬의 첫 번째 비제로 문자에 연결된 0이 아닌 문자와 일치합니다.

C=[,0]&<e/\0{/e\0*0$e|CoF^0oX
C=                             A rectangle R matches C if
  [,0]                         it is a single character other than 0
      &                        and
       <                       it is contained in a rectangle S which matches this pattern:
        e/\0{/e\0*0$e           R is the first nonzero character in the matrix:
        e                        S has an edge of the matrix over its top row,
         /0{/                    below that a rectangle of 0s, below that
             e\0*0$e             a row containing an edge, then any number of 0s,
                                 then R (the unescaped 0), then anything, then an edge.
                    |CoF^0oX    or R is next to another match of C:
                     CoF         S is a match of C (with fixed orientation)
                        ^0       followed by R,
                          oX     possibly rotated by any multiple of 90 dergees.

몇 가지 설명 : e입력 행렬의 가장자리 부분 인 너비 또는 높이가 0 인 사각형과 일치하며, $일치하는 "와일드 카드"입니다. e/\0{/e\0*0$e다음과 같이 표현식 을 시각화 할 수 있습니다.

+-e-e-e-e-e-e-e-+
|               |
|      \0{      |
|               |
+-----+-+-------+
e \0* |0|   $   e
+-----+-+-------+

표현식 CoX^0oX은 실제로 다음과 같이 구문 분석됩니다 ((CoF)0)oX. oFoX후위 연산자와 토큰 수단의 연결 수평 연결합니다. 은 ^다음 더 높은 우선 순위를주는 병렬 oX회전 전체 서브 표현에 적용되도록. 의 oF방향을 수정합니다C 이 회전 이후를 oX; 그렇지 않으면 회전 된 영어 읽기 순서에서 0이 아닌 첫 번째 좌표와 일치 할 수 있습니다.

e`C|:\0
e`       Match entire input against pattern:
    :    a grid whose cells match
  C      C
   |     or
     \0  literal 0.

즉, 0이 아닌 모든 문자가 첫 번째 문자에 연결되어야합니다. 그리드 지정 :자는 기술적으로 접미사 연산자이지만 C|:\0에 대한 구문 설탕입니다 (C|\0):.



0

파이썬 (2) , 211 (163) 150 바이트

m,w=input()
def f(i):a=m[i];m[i]=0;[f(x)for x in(i+1,i-1,i+w,i-w)if(x>=0==(i/w-x/w)*(i%w-x%w))*a*m[x:]]
f(m.index((filter(abs,m)or[0])[0]))<any(m)<1>q

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

종료 코드를 통해 출력됩니다. 입력은 1d리스트와 행렬의 너비입니다.

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