Nhận ra một cây nho


31

Lý lịch

Tôi có một loạt các hình ảnh đen trắng cũ và sần sùi. Một số trong số chúng mô tả dây leo leo trên tường, số khác thì không - nhiệm vụ của bạn là phân loại chúng cho tôi.

Đầu vào và đầu ra

Đầu vào của bạn là một mảng 2D hình chữ nhật gồm các bit A , được đưa ra ở bất kỳ định dạng thuận tiện nào. Nó sẽ không trống, nhưng nó không được đảm bảo chứa cả 0 và 1. Mảng mô tả một cây nho nếu các điều kiện sau đây giữ:

  • Hàng dưới cùng của A chứa ít nhất một 1. Đây là những gốc của cây nho.
  • Mỗi 1 trong A được kết nối với hàng dưới cùng bằng một đường dẫn 1 chỉ đi sang trái, phải và xuống (không lên và không theo đường chéo). Những con đường này là những nhánh của cây nho.

Đầu ra của bạn là một giá trị trung thực nhất quán nếu đầu vào mô tả một cây nho và một giá trị giả mạo nhất quán khác.

Ví dụ

Mảng này mô tả một cây nho:

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

Đầu vào này không mô tả một cây nho, vì có 1 ở giữa đường viền bên phải không được kết nối với rễ bằng một nhánh:

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

Mảng all-0 không bao giờ mô tả một cây nho, nhưng mảng all-1 luôn làm như vậy.

Quy tắc và tính điểm

Bạn có thể viết một chương trình đầy đủ hoặc một chức năng. Số byte thấp nhất sẽ thắng và các sơ hở tiêu chuẩn không được phép.

Các trường hợp thử nghiệm

Đầu vào trung thực:

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

Đầu vào giả:

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
Không nhận ra rằng cây nho không thể phát triển xuống dưới, có một ý tưởng hay bằng cách sử dụng các thành phần được kết nối của biểu đồ, thở dài ...
swish

@swish Tất cả điều đó có nghĩa là việc lần lượt loại bỏ từng hàng phải tiếp tục dẫn đến một biểu đồ được kết nối với một dòng 1s ở phía dưới.
Neil

Câu trả lời:


26

Ốc , 25 19 17 byte

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

Hãy thử trực tuyến!

Giải trình

Snails là một ngôn ngữ phù hợp với mô hình 2D được lấy cảm hứng từ regex, ban đầu được phát triển cho thử thách thiết kế ngôn ngữ phù hợp với mô hình 2D của chúng tôi .

Điều này &khiến Ốc sên thử mẫu từ mọi vị trí bắt đầu có thể và in 0hoặc 1tùy thuộc vào việc mẫu đó có bị lỗi trong bất kỳ vị trí nào trong số chúng hay khớp với tất cả chúng không.

Bây giờ Ốc sên có thể hoạt động với dấu ngoặc đơn ẩn, do đó mẫu này là tốc ký cho các mục sau:

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

Các ,hành vi như một *regex (tức là khớp 0 hoặc nhiều lần), trong khi đó +giống như trong regex (khớp một hoặc nhiều lần). Vì vậy, chúng tôi bắt đầu bằng cách khớp \0zthường xuyên khi cần thiết, khớp với một lần duy nhất 0và sau đó cho phép con ốc đặt lại hướng của nó một cách tùy ý z. Điều này cho phép các số không trong đầu vào, với điều kiện là một ô nho hợp lệ có thể được tìm thấy ở bất kỳ nơi nào khác.

Sau đó, chúng tôi khớp với ít nhất một \1dlr, khớp với một 1và sau đó cho phép ốc sên đặt lại hướng của nó xuống, trái hoặc phải. Lưu ý rằng nếu ô chúng tôi bắt đầu chứa 1thì chúng tôi chỉ khớp phần này. Về cơ bản, nó cho phép con ốc đi qua một cây nho từ một nhánh xuống rễ.

Cuối cùng, chúng ta cần đảm bảo rằng chúng ta đã chạm tới mặt đất bằng cách tìm kiếm một ô nằm ngoài giới hạn ( ~) bên dưới ( d).


1
Tôi ngạc nhiên khi thấy bất cứ ai cũng có thể làm theo tài liệu này :)
facerum

3

JavaScript (ES6), 135 byte

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

Lưu ý: Do giới hạn của loại số nguyên, chỉ hoạt động đối với dây leo có chiều rộng tối đa 31 ký tự. Giải thích: Mỗi hàng được theo chiều bit ANDed với hàng liền kề để xác định các điểm kết nối và sau đó gchức năng được sử dụng để mở rộng đệ quy hàng theo chiều ngang cho đến khi không thể mở rộng thêm nữa. Chẳng hạn, nếu hai hàng liền kề là 11101111011100 sau đó là các điểm kết nối 1010100và sau đó được mở rộng thành 1110110và sau 1110111đó sẽ thấy rằng hàng được kết nối. Nếu gchức năng thất bại thì nó trả về 0, điều này cũng khiến cho tất cả các gchức năng tiếp theo cũng bị lỗi và kết quả là sai lệch. Nếu gchức năng thành công, nó trả về hàng mới sau đó được truyền qua reduceđể kiểm tra hàng tiếp theo.

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

Tôi sẽ quy định rằng 31 ký tự đủ rộng và cách tiếp cận này là hợp lệ.
Zgarb

2

Python 2, 254 byte

Không có thư viện

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

Lưu ý rằng các thụt lề cấp hai và cấp ba được hình thành với các tab trong số byte.

Dùng thử trực tuyến


1

Sói - 254

Dành thời gian để thực hiện công việc này, vì vậy tôi sẽ để nó ở đây:

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&]]{}
)

Về cơ bản, tôi xây dựng một biểu đồ lưới với các cạnh được hướng lên trên, loại bỏ các đỉnh tương ứng với 0, kiểm tra xem các thành phần đỉnh dưới có chứa tất cả các đỉnh. Vô lý, tôi biết ...


2
Tại sao điều này không cạnh tranh?
Hạ cấp

1
Hiện tại chúng tôi sẽ xem xét điều này "không phải là một câu trả lời" vì nó không được đánh gôn. Nếu bạn chỉ đơn giản loại bỏ khoảng trắng không cần thiết và thêm số byte, tôi thấy không có lý do tại sao điều này sẽ không cạnh tranh.
Alex A.

0

Python + NumPy 204 202 195 byte

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

Mong đợi A kiến sẽ là một mảng numpy 2D.

Đưa ma trận, đệm các cột bằng không sang trái và phải và làm phẳng ma trận. slà một stprint chỉ vào phần tử bên trái, bên phải và bên dưới. Vòng lặp kiểm tra từng phần tử ngoại trừ dòng cuối cùng nếu nó 1và ít nhất một trong số các stprint của nó là 1, trả về Falsekhác. Sau đó, kiểm tra xem dòng cuối cùng có chứa bất kỳ1 .

Hai mẫu thử cho bạn:

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

Chỉnh sửa1: 1<0 ngắn hơnFalse

Chỉnh sửa2: flat là một thay thế tốt cho flatten()và sử dụng các trình lập bảng cho ý định thứ hai trong vòng lặp

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.