รู้จักเถาวัลย์


31

พื้นหลัง

ฉันมีภาพขาวดำและเม็ดเล็ก ๆ จำนวนมาก บางคนแสดงให้เห็นเถาวัลย์ที่ปีนขึ้นไปบนกำแพงส่วนคนอื่นไม่ทำ - งานของคุณคือการแบ่งพวกมันให้ฉัน

อินพุตและเอาต์พุต

อินพุตของคุณคืออาร์เรย์ 2 มิติของบิตA ที่กำหนดในรูปแบบที่สะดวก จะไม่ว่างเปล่า แต่ไม่รับประกันว่าจะมีทั้ง 0 และ 1 อาร์เรย์แสดงเถาวัลย์หากมีเงื่อนไขดังต่อไปนี้:

  • แถวด้านล่างของAมีอย่างน้อยหนึ่ง 1 เหล่านี้คือรากของเถา
  • ทุกๆ 1 ในAเชื่อมต่อกับแถวด้านล่างโดยเส้นทางของ 1s ที่ไปทางซ้ายขวาและลง (ไม่ใช่ขึ้นและไม่ใช่แนวทแยงมุม) เส้นทางเหล่านี้เป็นกิ่งก้านของเถาองุ่น

เอาท์พุทของคุณเป็นค่าความจริงที่สอดคล้องกันหากอินพุตแสดงให้เห็นถึงเถาวัลย์และค่าที่ผิดพลาดเป็นอย่างอื่น

ตัวอย่าง

อาร์เรย์นี้แสดงให้เห็นถึงเถา:

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 นั่นหมายความว่าการลบแต่ละแถวออกจะต้องดำเนินการต่อไปเพื่อให้ได้กราฟที่เชื่อมต่อกับบรรทัด 1s ที่ด้านล่าง
Neil

คำตอบ:


26

หอยทาก , 25 19 17 ไบต์

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

ลองออนไลน์!

คำอธิบาย

หอยทากเป็นภาษา 2D รูปแบบจับคู่แรงบันดาลใจจาก regex ซึ่งถูกพัฒนามาสำหรับรูปแบบ 2D ความท้าทายการออกแบบภาษาการจับคู่ของเรา

&หอยทากทำให้ลองรูปแบบจากตำแหน่งเริ่มต้นเป็นไปได้ทุกและพิมพ์0หรือ1ขึ้นอยู่กับว่ารูปแบบการล้มเหลวในใด ๆ ของพวกเขาหรือตรงกับในทั้งหมดของพวกเขา

ตอนนี้หอยทากสามารถทำงานกับวงเล็บโดยปริยายดังนั้นรูปแบบจึงเป็นแบบย่อสำหรับต่อไปนี้:

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

การ,กระทำที่เหมือน*ใน regex (เช่นจับคู่เป็นศูนย์หรือมากกว่าครั้ง) ในขณะ+ที่เหมือนกันในใน regex (ตรงกับหนึ่งครั้งหรือมากกว่า) ดังนั้นเราจึงเริ่มต้นโดยการจับคู่\0zบ่อยเท่าที่จำเป็นซึ่งตรงกับซิงเกิ้ลแล้วช่วยให้หอยทากเพื่อตั้งค่าทิศทางของพลด้วย0 zสิ่งนี้ยอมให้มีค่าเป็นศูนย์ในอินพุตหากสามารถหาเซลล์เถาวัลย์ที่ถูกต้องได้ทุกที่

จากนั้นเราจับคู่อย่างน้อยหนึ่งตัว\1dlrซึ่งจับคู่เดี่ยว1แล้วอนุญาตให้หอยทากรีเซ็ตทิศทางของมันลงซ้ายหรือขวา โปรดทราบว่าหากเซลล์ที่เราเริ่มต้นมี1แล้วเราจะจับคู่ส่วนนี้เท่านั้น มันช่วยให้หอยทากเคลื่อนที่ผ่านเถาวัลย์จากกิ่งไม้ลงไปที่ราก

ในที่สุดเราจำเป็นต้องตรวจสอบให้แน่ใจว่าเราได้ไปถึงพื้นด้วยการค้นหาเซลล์นอกขอบเขต ( ~) ด้านล่าง ( d)


1
ฉันประหลาดใจที่ทุกคนก็สามารถที่จะทำตามเอกสาร :)
feersum

3

JavaScript (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 อักขระเท่านั้น คำอธิบาย: แต่ละแถวเป็น bitwise ANDed กับแถวที่อยู่ติดกันเพื่อกำหนดจุดเชื่อมต่อจากนั้นgฟังก์ชันจะใช้ในการขยายแถวแบบวนซ้ำในแนวนอนจนกว่าจะสามารถขยายได้อีก ตัวอย่างเช่นหากสองแถวติดกันคือ1110111และ1011100จากนั้นจุดเชื่อมต่อที่มี1010100และนี่คือการขยายตัวนั้นไป1110110แล้ว1110111ซึ่งก็พบว่าแถวที่มีการเชื่อมต่อ หากgฟังก์ชันล้มเหลวฟังก์ชันจะส่งคืนค่าศูนย์ซึ่งทำให้gฟังก์ชันที่ตามมาทั้งหมดล้มเหลวเช่นกันและผลลัพธ์จะเป็นเท็จ หาก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

Python 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

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

โดยทั่วไปฉันสร้างกราฟกริดที่มีขอบชี้นำชี้ขึ้นเอาจุดยอดที่สอดคล้องกับ 0s ตรวจสอบว่าส่วนประกอบจุดยอดด้านล่างประกอบด้วยจุดยอดทั้งหมด ไร้สาระฉันรู้ ...


2
ทำไมสิ่งนี้จึงไม่ใช่การแข่งขัน
Downgoat

1
ในปัจจุบันเราจะพิจารณาว่า "ไม่ใช่คำตอบ" เนื่องจากไม่ได้เล่นกอล์ฟ หากคุณเพียงแค่ลบช่องว่างที่ไม่จำเป็นและเพิ่มจำนวนไบต์ฉันไม่เห็นเหตุผลว่าทำไมสิ่งนี้จึงไม่ใช่การแข่งขัน
Alex A.

0

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

คาดว่าAจะเป็นอาเรย์สองมิติ

นำเมทริกซ์นำแผ่นศูนย์คอลัมน์ไปทางซ้ายและขวาและทำให้เมทริกซ์แบน sเป็นลายฉลุที่ชี้ไปทางซ้ายขวาและส่วนล่าง การวนซ้ำจะตรวจสอบแต่ละองค์ประกอบยกเว้นบรรทัดสุดท้ายหากเป็น1และอย่างน้อยหนึ่งใน stencil ของมันคือ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: flatเป็นทางเลือกที่ดีในการflatten()ใช้ tabulators สำหรับความตั้งใจที่สองในลูป

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.