ตรวจสอบว่าองค์ประกอบที่ไม่เป็นศูนย์ทั้งหมดในเมทริกซ์เชื่อมต่อกันหรือไม่


19

การป้อนข้อมูล:

เมทริกซ์ที่มีจำนวนเต็มในช่วง[0-9]

ท้าทาย:

ตรวจสอบว่าองค์ประกอบที่ไม่ใช่ศูนย์ทั้งหมดเชื่อมต่อกันในแนวตั้งและ / หรือแนวนอน

เอาท์พุท:

ค่า truthyถ้าทั้งหมดที่มีการเชื่อมต่อและค่า falsyถ้ามีไม่ใช่ศูนย์องค์ประกอบ / กลุ่มที่ไม่ได้เชื่อมต่อกับองค์ประกอบอื่น ๆ / กลุ่ม

กรณีทดสอบ:

กรณีทดสอบถูกคั่นด้วยบรรทัด กรณีทดสอบสามารถพบได้ในรูปแบบที่สะดวกกว่าได้ที่นี่ ( Kudos ถึง Dada )

ต่อไปนี้เป็นสิ่งที่เชื่อมต่อกันและควรจะคืนค่าความจริง:

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

นี่คือดังนั้นการส่งสั้นที่สุดในแต่ละภาษาชนะ คำอธิบายได้รับการสนับสนุน!


แรงบันดาลใจจากความท้าทายนี้


บางทีอินพุตควรมีเพียงหนึ่งและศูนย์ (หรือความจริงและ falsys) เพราะนี่คือหลักเกี่ยวกับองค์ประกอบที่เชื่อมต่อ
NikoNyrh

เราสามารถรับอินพุตเป็นอาร์เรย์ 1 มิติและจำนวนคอลัมน์ได้หรือไม่?
OVS

@ แน่นอน ฉันไม่เห็นว่ามันจะให้ประโยชน์แก่คุณมากกว่าคนอื่น ๆ ที่ได้ตอบไปแล้ว
Stewie Griffin

2
ที่เกี่ยวข้อง : คุณต้องเปลี่ยนค่าศูนย์เป็นจำนวนเท่าใดเพื่อเชื่อมโยงองค์ประกอบที่ไม่ใช่ศูนย์ทั้งหมด
dylnan

ที่เกี่ยวข้อง : นับจำนวนส่วนประกอบ (แต่มีรายการแนวทแยงมุมติดกัน)
Misha Lavrov

คำตอบ:


9

เรติน่า 0.8.2 , 80 77 ไบต์

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

ลองออนไลน์! แก้ไข: บันทึก 1 ไบต์ขอบคุณ @FryAmTheEggman คำอธิบาย:

T`d`@1

ลดความซับซ้อนของอาร์เรย์@s และ1s

1`1
_

เปลี่ยนหนึ่งไป1_

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

เติมน้ำท่วมจาก_การที่อยู่ติดกัน1s

^\D+$

ทดสอบว่ามี1ของเหลือหรือไม่


@FryAmTheEggman ขอบคุณและคุณให้ความคิดกับฉันเกี่ยวกับวิธีการบันทึกอีกสองไบต์เช่นกัน!
Neil

7

JavaScript (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 ()จะค้นหาเซลล์ที่ไม่เป็นศูนย์ก่อน (ตราบใดที่ค่าสถานะz ที่กำหนดทั่วโลกถูกตั้งค่าเป็น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<

นี้จะช่วยให้เมทริกซ์ที่มีทุกคนเป็นtruthyการส่งออกหรือเมทริกซ์ที่มีอย่างน้อยเป็นศูนย์เป็นfalsy ลองออนไลน์!

นอกจากนี้คุณยังสามารถตรวจสอบความจริง / ความเท็จเพิ่มสาขา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 ถือว่าอาร์เรย์ของตัวเลขเป็นจริง IFF ซึ่งไม่มีเลขศูนย์ mathworks.com/help/matlab/ref/if.html (ลบความคิดเห็นก่อนหน้านี้)
Sparr

@Sparr (จริง ๆ แล้วถ้ามันไม่มีเลขศูนย์และไม่ว่างเปล่า ) ฉันก็สับสนเมื่อฉันได้เรียนรู้ว่าอาเรย์ที่ไม่มีข้อยกเว้นนั้นเป็นความจริงในภาษาอื่น
Luis Mendo


4

C, 163 ไบต์

ขอบคุณ @ 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;}

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

ลองออนไลน์!

คลี่:

*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

Perl, 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

Java 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

(ไม่มี Python Eval แน่นอน)
user202729

1

Haskell , 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

สกัดจากSolve Hitori Puzzles

indices mแสดงที่(line,cell)ตั้งของกริดอินพุต

filter((/=0).(m!)) กรองสถานที่ทั้งหมดด้วยค่าที่ไม่เป็นศูนย์

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

สิ่งสกปรก 37 ไบต์

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

พิมพ์1สำหรับการจับคู่และ0ไม่มีการจับคู่ ลองออนไลน์!

คำอธิบาย

nonterminal Cจับคู่อักขระที่ไม่ใช่ศูนย์ใด ๆ ที่เชื่อมต่อกับอักขระที่ไม่ใช่ศูนย์แรกของเมทริกซ์ในลำดับการอ่านภาษาอังกฤษ

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จับคู่สี่เหลี่ยมที่มีความกว้างหรือความสูงเป็นศูนย์ซึ่งเป็นส่วนหนึ่งของขอบของเมทริกซ์อินพุตและ$เป็น "สัญลักษณ์ตัวแทน" ที่ตรงกับทุกอย่าง การแสดงออกe/\0{/e\0*0$eสามารถมองเห็นได้ดังนี้

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

การแสดงออกCoX^0oXถูกแยกวิเคราะห์จริงเป็น((CoF)0)oX; oFและoXผู้ประกอบการ postfix และเรียงต่อกันของสัญญาณหมายถึงการเรียงต่อกันในแนวนอน การ^วางเคียงกันจะมีลำดับความสำคัญสูงกว่าoXดังนั้นการหมุนจึงถูกนำไปใช้กับนิพจน์ย่อยทั้งหมด oFแก้ไขการวางแนวของCหลังจากที่มีการหมุนโดยoX; ไม่เช่นนั้นมันจะจับคู่ค่าที่ไม่ใช่ศูนย์แรกในลำดับการอ่านภาษาอังกฤษ

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

ซึ่งหมายความว่าอักขระที่ไม่ใช่ศูนย์ทั้งหมดต้องเชื่อมต่อกับอักขระตัวแรก ตัวระบุตาราง:เป็นเทคนิคที่ผู้ประกอบการ postfix แต่เป็นน้ำตาลประโยคสำหรับC|:\0(C|\0):



0

Python 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.