포도 나무를 인식


31

배경

오래되고 거친 흑백 이미지가 많이 있습니다. 그들 중 일부는 벽에 오르는 덩굴을 묘사하지만 다른 것들은 그렇지 않습니다. 당신의 임무는 나를 위해 분류하는 것입니다.

입력과 출력

입력은 편리한 형식으로 지정된 비트 A 의 직사각형 2D 배열입니다 . 비어 있지는 않지만 0과 1을 모두 포함한다고 보장 할 수는 없습니다. 다음 조건이 충족되는 경우 배열은 포도 나무를 나타냅니다.

  • A 의 맨 아랫 줄 에는 최소한 1 개가 들어 있습니다. 이들은 포도 나무의 뿌리입니다.
  • A의 모든 1 은 왼쪽, 오른쪽 및 아래쪽 (대각선이 아님)으로 만 이동하는 경로 1로 맨 아래 행에 연결됩니다. 이 길은 포도 나무의 가지입니다.

입력 값이 포도 나무를 나타내는 경우 출력은 일관된 진실 값이며, 그렇지 않으면 일관된 거짓 값입니다.

이 배열은 포도 나무를 나타냅니다.

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

이 입력은 포도 나무를 나타내지 않습니다. 오른쪽 경계의 중간에는 지점에 의해 뿌리에 연결되지 않은 1이 있기 때문에 :

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

all-0 배열은 덩굴을 묘사하지 않지만 all-1 배열은 항상 그렇습니다.

규칙과 득점

전체 프로그램이나 함수를 작성할 수 있습니다. 바이트 수가 가장 적고 표준 허점이 허용되지 않습니다.

테스트 사례

진실한 입력 :

1

0
1
1

01
11

0000
0111
1100
1001

1111
1111
1111
1111

001001
011001
010111
110101
011101
001011

1011011
1001001
1111111
0100000
0111111
1111001
1001111
1111101

0000000
0011100
0010100
0011100
0001000
1111111
0001000
0011100
0010100
0010100

잘못된 입력 :

0

1
0

10
01

000
000
000

011
110
000

111111
000000
101011
111001

010010
001000
000010
110001

001100
111111
110101
010011
111011

000110
010111
010101
011110
001101

11000000
10110001
10011111
11110001
01100011
00110110
01101100
01100001
01111111

1
포도 나무가 아래쪽으로 자랄 수 없다는 것을 몰랐고, 그래프의 연결된 구성 요소를 사용하여 좋은 생각을 가졌습니다 ...
swish

@swish 즉, 각 행을 차례로 제거하면 맨 아래에 1s의 선에 연결된 그래프가 계속 생성되어야합니다.
Neil

답변:


26

달팽이 , 25 19 17 바이트

&
\0z),(\1dlr)+d~

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

설명

달팽이는 정규식에서 영감을 얻은 2D 패턴 일치 언어로, 원래 2D 패턴 일치 언어 디자인 과제를 위해 개발 되었습니다 .

&차종 달팽이는 모든 가능한 시작 위치 및 인쇄에서 패턴 시도 0또는 1패턴이 모두 그들 또는 경기의 실패 여부에 따라.

이제 달팽이는 암시 적 괄호로 작업 할 수 있으므로 패턴은 다음과 같은 축약 형입니다.

(\0z),(\1dlr)+d~

,유사한 행동 *(가), 반면 (즉, 0 회 이상 일치) 정규식 +정규식 (한 번 이상 일치)와 동일하다. 따라서 \0z필요에 따라 자주 일치시키는 것으로 시작 합니다. 단일 일치 0하고 달팽이가 방향을 임의로 재설정 할 수 있습니다 z. 다른 곳에서 유효한 포도 나무 세포를 찾을 수 있다면 입력에 0을 허용합니다.

그런 다음 하나 이상 \1dlr을 일치 1시킵니다 . 단일 과 일치 하고 달팽이가 방향을 아래, 왼쪽 또는 오른쪽으로 재설정 할 수 있습니다. 시작한 셀에 a가 포함되어 있으면 1이 부분 만 일치 한다는 점에 유의하십시오 . 기본적으로 달팽이가 가지에서 뿌리까지 덩굴을 통과 할 수 있습니다.

마지막으로 ( ~) 아래의 범위를 벗어난 셀 ( ) 을 찾아지면에 도달했는지 확인해야합니다 d.


1
누구나 문서를 볼 수 있다는 것에 놀랐습니다. :)
feersum

3

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

s=>s.replace(/^[^1]*\n/,``).split`
`.map(s=>+`0b${s}`).reverse(g=(n,m,o=(m<<1|m|m>>1)&n)=>n-m?o-m&&g(n,o):n).reduce((m,n,i)=>g(n,n&m))

참고 : 정수 유형의 제한으로 인해 최대 31 자의 덩굴에만 작동합니다. 설명 : 각 행은 인접한 행과 비트 단위 AND 연결되어 연결점을 판별 한 후 g더 이상 확장 할 수 없을 때까지 행을 수평으로 재귀 적으로 확장하는 데 사용됩니다. 예를 들어, 두 개의 인접한 행이있는 경우 11101111011100그 접속점이 1010100이 다음에 확장 된 1110110후와 1110111다음 행이 연결된 것을 발견한다. 은 IF g함수에 실패 그 이후의 모든 원인이 제로 반환 g기능도 실패하고, 그 결과는 다음 falsy입니다. 은 IF g함수가 성공은 다음을 통해 전파되는 새 행 반환 reduce다음 행을 테스트합니다.

s=>s.replace(/^[^1]*\n/,``)         Remove irrelevant leading "blank" rows
    .split`\n`                      Split into lines
    .map(s=>+`0b${s}`)              Convert into binary
    .reverse(                       Process from bottom to top
     g=(n,m,o=(m<<1|m|m>>1)&n)=>     Expand row horizontally
      n-m?o-m&&g(n,o):n)             Check whether rows are connected
    .reduce((m,n,i)=>g(n,n&m))      Check all rows

31 자 길이로 충분하다고 판단하고이 방법은 유효합니다.
Zgarb

2

파이썬 2, 254 바이트

도서관 없음

def f(A,r=0,c=-1):
 B=A[r];R=len(A)-1;C=len(B);i=1 in A[R]
 if c<0:
    for j in range(R*C+C):
        if A[j/C][j%C]:i&=f(A,j/C,j%C)
    return i&1
 _=B[c];B[c]=0;i=_&(r==R)
 if _:
    if c>0:i|=f(A,r,c-1)
    if r<R:i|=f(A,r+1,c)
    if c<C-1:i|=f(A,r,c+1)
 B[c]=_;return i

두 번째 및 세 번째 수준 들여 쓰기는 바이트 수의 탭으로 구성됩니다.

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


1

볼프람-254

이 작업을하는 데 시간이 걸리므로 여기에 그대로 두겠습니다.

f[s_]:=(
v=Characters@StringSplit@s;
{h,w}=Dimensions@v;
g=GridGraph@{w,h};
r=First/@Position[Flatten@v,"0"];
g=VertexDelete[Graph[VertexList@g,
EdgeList@g/.x_y_/;Abs[x-y]>1yx],r];
v=VertexList@g;
v≠{}∧v~Complement~VertexOutComponent[g,Select[v,#>w h-w&]]{}
)

기본적으로 지시 된 모서리가 위를 향한 그리드 그래프를 작성하고 0에 해당하는 정점을 제거하고 맨 아래 정점 구성 요소에 모든 정점이 포함되어 있는지 확인하십시오. 말도 안 돼요 ...


2
이것이 경쟁이 아닌 이유는 무엇입니까?
Downgoat

1
현재 우리는 이것이 골프가 아니기 때문에 "답이 아님"을 고려할 것입니다. 불필요한 공백을 제거하고 바이트 수를 추가하면 이것이 경쟁이 아닌 이유가 없습니다.
Alex A.

0

파이썬 NumPy와 + 204 202 195 바이트

from numpy import*
def f(A):
 r,c=A.shape
 z,s=zeros((r,1)),array([0,2,c+3])
 B=hstack((z,A,z)).flat
 for i in range(1,(r-1)*(c+2)):
    if B[i]and not any(B[s]):return 1<0
    s+=1
 return any(B[i:])

A2D numpy 배열 일 것으로 예상 됩니다.

행렬을 취하고 0 열을 왼쪽과 오른쪽으로 채우고 행렬을 평평하게합니다. s왼쪽, 오른쪽 및 아래쪽 요소를 가리키는 스텐실입니다. 루프는 마지막 라인을 제외한 각 요소를 검사 1하고 스텐실 중 하나 이상이이면 그렇지 않으면 1반환 False합니다. 그런 다음 마지막 줄에가 포함되어 있는지 확인하십시오 1.

두 가지 테스트 사례 :

I1 = '001001\n011001\n010111\n110101\n011101\n001011'
A1 = array([int(c) for c in I1.replace('\n','')]).reshape(6,6)
print f(A1) #True

I2 = '001100\n111111\n110101\n010011\n111011'
A2 = array([int(c) for c in I2.replace('\n','')]).reshape(5,6)
print f(A2) #False

Edit1 : 1<0보다 짧습니다False

Edit2 : 루프에서 두 번째 의도를 위해 tabulator를 사용하고 사용 flat하는 훌륭한 대안 flatten()입니다.

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