ตรวจสอบว่าที่ดินถูกล้อมรั้วไว้เต็มหรือไม่


19

ลองนึกภาพอาร์เรย์แบบสองมิติของค่าบูลีนที่ 0s เป็นตัวแทนของสี่เหลี่ยมของหญ้าบนที่ดินรูปสี่เหลี่ยมผืนผ้าและ 1s เป็นตัวแทนของรั้ว

เขียนฟังก์ชั่นที่ยอมรับอาร์เรย์ 2D เป็นอินพุตและกำหนดว่าคุณสามารถเดินทางจากพื้นที่หนึ่งไปยังพื้นที่หญ้าอื่น ๆ โดยใช้การเคลื่อนไหวแบบทิศเหนือ / ตะวันออก / ตะวันตก / ใต้โดยไม่ต้องวิ่งเข้าไปในรั้ว

หากพื้นที่ใด ๆ ของหญ้าในอาเรย์นั้นถูกล้อมรอบด้วยรั้ว (หมายความว่าคุณไม่สามารถเดินทาง N / E / W / S เพื่อไปยังพื้นที่อื่น ๆ ของหญ้าในอาเรย์) ฟังก์ชั่นควรกลับเท็จ ไม่เช่นนั้นควรกลับมาจริง

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

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

(should return true)

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

(should return false, since the middle 0 in the top row is fully enclosed)

รหัสการทำงานที่สั้นที่สุดชนะ ฉันจะเลือกผู้ชนะหลังจากผ่านไปหนึ่งสัปดาห์หรือไม่มีการส่งผลงานใหม่ภายใน 24 ชั่วโมง


คุณสามารถห้ามผู้ประกอบการไบนารี่ได้หรือไม่? ฉันชอบที่จะเห็นสิ่งที่ผู้คนจะเกิดขึ้นกับ
Pierre Arlaud

ฉันเชื่อว่านี่คล้ายกับปัญหาของ USACO จากปีที่แล้ว (ฤดูกาล 2012/2013) มีบางกรณีทดสอบขนาดใหญ่ที่สามารถเข้าถึงได้มี ...
apnorton

ขนาดของอาร์เรย์จะเป็น 5 * 5 หรือไม่
ProgramFOX

1
@ProgramFOX สมมติว่าอาร์เรย์อาจมีความสูงใด ๆ ความกว้างใดก็ได้ และเอาท์พุทอะไรก็ได้แบบบูล
jawns317

1
สิ่งที่เกี่ยวกับเมทริกซ์ 3X3 1 1 1; 1 0 1; 1 1 1? มีหนึ่งเซลล์หญ้าอยู่ตรงกลาง สายตาเซลล์ของหญ้าที่อยู่ตรงกลางนั้นล้อมรอบด้วยรั้ว แต่โดยความหมายของคุณมันไม่ได้
emory

คำตอบ:


1

Matlab 45

input('');c=bwconncomp(~ans,4);c.NumObjects<2

1
@ jawns317 ฉันไม่เห็นว่าทำไมนี่คือคำตอบที่ยอมรับได้ นี่ไม่ใช่ฟังก์ชั่น อีกคำตอบเดียวที่ไม่ใช่ฟังก์ชั่นยอมรับจาก stdin อันนี้ไม่ได้ทำอย่างนั้น
Tim Seguine

1
การยอมรับอินพุตมาตรฐานสามารถทำได้เช่นinput('');c=bwconncomp(~ans,4);c.NumObjects<2นี้จะทำให้มี 45 ตัวอักษร
Dennis Jaheruddin

7

APL (39)

{∧/,⊃{⍺∨⊖⍵}/{⍵∨(∧\~⍵)∨⌽∧\⌽~⍵}¨s,⊖¨s←⊂⍵}

การใช้งาน:

      board1 board2
 0 0 0 0 0  0 1 0 1 0 
 0 1 0 0 0  0 1 1 0 0 
 0 1 1 1 1  0 0 0 0 0 
 0 0 0 0 0  0 0 0 1 0 
 0 0 0 1 1  1 1 1 1 0 
      {∧/,⊃{⍺∨⊖⍵}/{⍵∨(∧\~⍵)∨⌽∧\⌽~⍵}¨s,⊖¨s←⊂⍵} ¨ board1 board2
1 0

9
ประโยชน์ของ APL คือดูเหมือนว่ามีสัญญาณรบกวนสายซึ่งไม่มีใครต้องการตรวจสอบว่าถูกต้อง
Tim Seguine

@Tim ทุกคนสามารถดาวน์โหลดล่ามเพื่อเรียกใช้และตรวจสอบได้
Gareth

3
@Getheth ใช่ความเห็นควรจะเป็นลิ้นในแก้ม
Tim Seguine

@Tim โอ้ขอโทษ คิดถึงว่า :-(
Gareth

4

Mathematica, 60 58 ตัวอักษร

f=Max@MorphologicalComponents[1-#,CornerNeighbors->1>2]<2&

การใช้งาน:

f[{{0, 0, 0, 0, 0}, {0, 1, 0, 0, 0}, {0, 1, 1, 1, 1}, {0, 0, 0, 0, 0}, {0, 0, 0, 1, 1}}]

จริง

f[{{0, 1, 0, 1, 0}, {0, 1, 1, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 1, 0}, {1, 1, 1, 1, 0}}]

เท็จ


2
ความยาวเท่ากันf=Max@WatershedComponents[Image@#,CornerNeighbors->1>2]<2&
Dr. belisarius

3

ทับทิม, 202 198 193

a=$<.read.split('
').map(&:split)
f=->x,y{a[x][y]=1
[[-1,0],[1,0],[0,-1],[0,1]].map{|o|d,e=x+o[0],y+o[1]
f[d,e]if a[d]&&a[d][e]==?0}}
f[i=a.index{|x|x.index ?0},a[i].index(?0)]
p !(a.join=~/0/)

เติมน้ำท่วมแล้วตรวจสอบเพื่อดูว่ามี 0 ใดที่เหลืออยู่หรือไม่


ประณาม! ถ้าฉันไม่ได้ทดสอบโค้ดของฉันก่อนฉันคงจะเร็วขึ้น ;)
Tim Seguine

@Tim แต่ถ้าอย่างนั้นมันจะผิด! : P
Doorknob

3

PHP 147 202 177 165 149ไบต์

แก้ไขฉันเอาชนะแฮ็ค gzip ด้วยโซลูชัน php จริง

อินพุตยาว .... เล็กน้อยเป็นสตริงข้อความ, ไม่มีช่องว่าง, แถวคั่นด้วยบรรทัดใหม่ มันท่วมด้วยcs แล้วตรวจสอบเพื่อดูว่ามีเลขศูนย์เหลืออยู่หรือไม่ ในลูปฉันใช้expเป็นขอบเขตบนอย่างหยาบกับจำนวนการวนซ้ำที่ต้องการ ฉันใช้ประโยชน์จากความสมมาตรเพื่อจัดการเคสที่ซ้ำกันโดยใช้โค้ดน้อยกว่า

function f($s){$r=strpos;$n=$r($s,'
');$s[$r($s,'0')]=c;for(;$i++<1<<$n;)$s=strrev(ereg_replace('0(.{'.$n.'})?c','c\1c',$s));return!1==$r($s,'0');}

นี่คือกรณีทดสอบที่ไม่ดี

<?php
$s1="00000
01000
01111
00000
00011";

$s2="01010
01100
00000
00010
11110";

function f($s){
    $n=strpos($s,"\n");
    $s[strpos($s,'0')]=c;
    for(;$i<strlen($s);++$i)
        $s=strrev(ereg_replace(
            '0(.{'.$n.'})?c',
            'c\1c'
            ,$s));
    return!1===strpos($s,'0');
}

var_dump(f($s1));
var_dump(f($s2));

3

Excel VBA, 305 215 ไบต์

ใช่ฮ่าฮ่า VBAแต่ธรรมชาติของเมทริกซ์ของปัญหาเสนอแนะวิธีแก้ปัญหาที่ใช้งานได้จริงใน Excel อาจน่าสนใจ เห็นได้ชัดว่า VBA จะไม่รวบรัดที่สุด แต่ฉันคิดว่ามันสมเหตุสมผล

น้ำท่วมครั้งนี้เต็มไปจากจุดเริ่มต้นโดยพลการแล้วตรวจสอบว่ามี "หญ้า" เหลืออยู่หรือไม่

R คือช่วงของเวิร์กชีทที่มี 1 และ 0 เป็นตัวแทนของรั้วและหญ้าตามที่กำหนดไว้ในปัญหา โบนัสสนามเด็กเล่นไม่จำเป็นต้องเป็นรูปสี่เหลี่ยมผืนผ้าหรือต่อเนื่องกัน

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

ตัวอย่างเช่นจะคืนค่าเท็จ ไม่สามารถเข้าถึงค่าศูนย์ทางด้านขวาจากศูนย์ทางซ้าย สนามที่ผิดปกติจะไม่ทำลายมัน

Function F(R)
L R, R.Find(0)
F = Not IsNumeric(R.Find(0))
End Function

Sub L(R, S As Range)
If S Or IsEmpty(S) Then Exit Sub
S = 1
L R, S.Offset(1, 0)
L R, S.Offset(-1, 0)
L R, S.Offset(0, 1)
L R, S.Offset(0, -1)
End Sub

หมายเหตุบางประการเกี่ยวกับการเล่นกอล์ฟ

ฉันคิดว่าตัวอักษรบางตัวอาจถูกตัดออกได้ถ้าความต้องการนั้นกลับเป็น 1 และ 0 แต่ไม่เพียงพอที่จะทำให้คุ้มค่า

VBA ยืนกรานที่ช่องว่าง (a = b vs a = b) ซึ่งไม่ได้ช่วยนับถ่าน

S จะต้องมีการประกาศอย่างชัดเจนว่าเป็นช่วง หากยังมีตัวแปรอยู่มันจะเปลี่ยนเป็นค่าช่วงแทนที่จะเป็นช่วง

อาจเป็นวิธีที่ดีกว่าในการแยกน้ำท่วม? ฉันไม่สามารถเกิดลูปที่บันทึกตัวอักษรใด ๆ เพื่อส่ง N / E / S / W ได้

แก้ไข: นำเคสพื้นฐานมาเติมน้ำท่วมอีกครั้งโดยทำการตัดออกเล็กน้อยโดยตรวจสอบว่าเป็นเคสฐานหลังการเรียกซ้ำมากกว่าการป้องกันการเรียกซ้ำ


2

Python (219 ไบต์)

ไม่ใช่ที่สั้นที่สุด แต่เป็นครั้งแรกที่ฉันลองที่นี่ดังนั้นฉันจึงภูมิใจ:

def f(n):
 m=[int(c) for c in n if c!='\n']
 for i in range(len(m)):
  if m[i]<1:m[i]=2;break
 g(m,n.find('\n'),i);return not 0in m
def g(n,w,i):
 for x in i-w,i-1,i+1,i+w:
  if 0<=x<len(n):
   if n[x]<1:n[x]=2;g(n,w,x)

ข้อมูลที่ป้อนควรเป็นสตริงของ 0s & 1s โดยที่แถวถูกคั่นด้วยอักขระบรรทัดใหม่ (\ n)

ตัวอย่างการใช้งาน:

>>> f("00000\n01000\n01111\n00000\n00011")
True
>>> f("01010\n01100\n00000\n00010\n11110")
False

คุณสามารถรวมสองคนสุดท้ายถ้างบเป็นหนึ่งด้วยandผมคิดว่ามันจะช่วยประหยัดตัวอักษรบาง
ทิม Seguine

คุณสามารถใช้ tabulator เป็น 8 ช่องว่าง
Konrad Borowski

2

Python (196)

เติมน้ำท่วมมาตรฐาน

g=raw_input()
m=g.find(' ')
g=g.replace(' ','')
V={}
def D(V,x):
 if V.get(x,0)or g[x]=='1':return
 V[x]=1;[D(V,x+i)for i in 1,-1,m,-m if 0<=x+i<len(g)]
D(V,g.find('0'))
print len(V)==g.count('0')

นำเมทริกซ์ผ่าน STDIN โดยแต่ละแถวคั่นด้วยช่องว่างเดียว ตัวอย่างเช่น "01010 01100 00000 00010 11110"


2

Mathematica 53

f=Max@(Symbol@@Names@"I*`i*B*l")[Image[1-#],0,1>2]<2&

มันเรียกฟังก์ชั่นภายในซึ่งจะคล้ายกับImage`MorphologicalOperationsDump`imageBinaryLabelMorphologicalComponents

f[{{0, 0, 0, 0, 0}, {0, 1, 0, 0, 0}, {0, 1, 1, 1, 1}, {0, 0, 0, 0, 0}, {0, 0, 0, 1, 1}}]
f[{{0, 1, 0, 1, 0}, {0, 1, 1, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 1, 0}, {1, 1, 1, 1, 0}}]

จริง

เท็จ


1

PHP (286 ตัวอักษร)

ทางยาวเกินไปฉันอาจไปทางยาวไกล

function D($a){$x=count($a);$y=count($a[0]);for($i=0;$i<$x;$i++)$a[$i][-1]=$a[$i][$y]=1;for($j=0;$j<$y;$j++)$a[-1][$j]=$a[$x][$j]=1;for($i=0;$i<$x;$i++){for($j=0;$j<$y;$j++){if($a[$i][$j]!=1){if($a[$i][$j-1]==1&&$a[$i][$j+1]==1&&$a[$i-1][$j]==1&&$a[$i+1][$j]==1)return 0;}}}return 1;}

Non-แข็งแรงเล่นกอล์ฟ:

function D($a)
{
$x=count($a);
$y=count($a[0]);
for ($i=0;$i<$x;$i++)
    $a[$i][-1]=$a[$i][$y]=1;
for ($j=0;$j<$y;$j++)
    $a[-1][$j]=$a[$x][$j]=1;
for ($i=0;$i<$x;$i++)
{
    for ($j=0;$j<$y;$j++)
    {
        if ($a[$i][$j] != 1)
        {
            if ($a[$i][$j-1] == 1 && $a[$i][$j+1] == 1 && $a[$i-1][$j] == 1 && $a[$i+1][$j] == 1)
                return 0;
        }
    }
}
return 1;
}

สิ่งนี้ไม่ถูกต้อง มันจะตรวจสอบเพื่อดูว่าไม่มีศูนย์เดียวซึ่งล้อมรอบด้วยศูนย์หรือไม่ มีวิธีการที่ซับซ้อนมากขึ้นในการปิดศูนย์
Tim Seguine

แน่นอนว่าคุณพูดถูก ฉันกำลังมองหาวิธีอื่นในการแก้ปัญหานี้โดยไม่ต้องเติมน้ำท่วมฉันเดาว่าการค้นหาของฉันจะดำเนินต่อไป!
Vereos

มันเป็นเพียงปัญหาการเข้าถึงกราฟและการเติมน้ำท่วมในกรณีนี้โดยทั่วไปคือฟลอยด์ - วอร์ฮอลล์โดยไม่ต้องสร้างหรือแสดงกราฟการเข้าถึงอย่างชัดเจน คุณสามารถลองดึงกราฟออกมาและทำการปิดสกรรมเองได้ แต่เดาว่ามันจะนานกว่านี้
Tim Seguine

1

C #, 235 ไบต์

int[][]D;int w,h,n;bool Q(int x,int y){var r=x>=0&&x<w&&y>=0&&y<h&&(D[x][y]++==0);if(r){Q(x-1,y);Q(x+1,y);Q(x,y+1);Q(x,y-1);}return r;}
bool P(int[][]B){D=B;w=D[0].Length;h=D.Length; for(int i=0;i<w*h;i++)if(Q(i%w,i/w))n++;return n==1;}

มันพยายามที่จะท่วมเต็มทุกเซลล์ในกระดานมันทำให้การเติมน้ำท่วมเพียงครั้งเดียวนั้นกลับมาจริง

bool R( int x, int y)
{
    var r = (x >= 0 && x < w && y >= 0 && y < h && D[x, y]++ == 0);
    if (r)
    {
        R(x-1, y);
        R(x+1, y);
        R(x, y+1);
        R(x, y-1);
    }
    return r;
}

public bool Do()
{
    D = Board1;
    w = D.GetLength(0);
    h = D.GetLength(1);
    for (int x = 0; x < w; x++) for (int y = 0; y< h; y++) if (R(x, y)) n++;
    return n == 1;
}

0

Python 2.X + 3.X: 335 ตัวละคร

แข็งแรงเล่นกอล์ฟ:

def f(n):
 x,y=0,0
 z=lambda x,y:y<len(n)and x<len(n[0])and n[x][y]!=1
 while not z(x,y):
  y+=1
  if y==len(n):
   y=0
   x+=1
  if x==len(n[0]):
   return False
 t=set([(x,y)])
 v=set()
 while t:
  (x,y)=t.pop()
  v|=set([(x,y)])
  if z(x+1,y):
   t|=set([(x+1, y)])
  if z(x,y+1):
   t|=set([(x, y+1)])
 return len(v)+sum(map(sum,n))==len(n)*len(n[0])

Ungolfed:

def f(n):
    """In the following filed, starting from a 0: is it possible to
       get to every other 0?

        >>> f([[0,0,0,0,0],\
               [0,1,0,0,0],\
               [0,1,1,1,1],\
               [0,0,0,0,0],\
               [0,0,0,1,1]])
        True
        >>> f([[0,1,0,1,0],\
               [0,1,1,0,0],\
               [0,0,0,0,0],\
               [0,0,0,1,0],\
               [1,1,1,1,0]])
        False
        >>> f([[1,1,1,1,1],\
               [1,1,1,1,1],\
               [1,1,1,1,1],\
               [1,1,1,1,1],\
               [1,1,1,1,1]])
        False
        >>> f([[1,1,1,1,1],\
               [1,1,1,1,1],\
               [1,1,1,1,1],\
               [1,0,1,1,1],\
               [1,1,1,1,1]])
        True
        >>> f([[1,1,1,1,1],\
               [1,1,1,1,1],\
               [0,1,1,1,1],\
               [1,0,1,1,1],\
               [1,1,0,1,1]])
        False
        >>> f([[1,1,1,1,1],\
               [1,1,1,1,1],\
               [1,1,1,1,1],\
               [1,1,1,1,1],\
               [1,1,1,1,0]])
        True
    """
    x, y = 0,0
    isValid = lambda x,y: y<len(n) and x<len(n[0]) and n[x][y] != 1
    for i in range(len(n)*len(n[0])):
        x = i%len(n)
        y = i/len(n)
        if isValid(x,y):
            break

    while not isValid(x,y):
        y += 1
        if y == len(n):
            y = 0
            x += 1
        if x == len(n[0]):
            return False # Problem is not clearly defined here
    toGo=set([(x,y)])
    visited=set()
    while toGo:
        (x,y) = toGo.pop()
        visited |= set([(x,y)])
        if isValid(x+1,y):
            toGo |= set([(x+1, y)])
        if isValid(x,y+1):
            toGo |= set([(x, y+1)])
    return len(visited)+sum(map(sum,n)) == len(n)*len(n[0])

if __name__ == "__main__":
    import doctest
    doctest.testmod()

คุณสามารถย้ายเวอร์ชั่น golfed ไปด้านบนได้หรือไม่? บางคนมีสคริปต์ผู้ใช้สำหรับไซต์นี้ซึ่งนับจำนวนอักขระในบล็อกแรกของรหัส
Gareth

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