Bir matristeki sıfır olmayan tüm öğelerin bağlı olup olmadığını kontrol edin


19

Giriş:

[0 - 9] aralığında tamsayılar içeren bir matris .

Meydan okuma:

Sıfır olmayan tüm öğelerin birbirine dikey ve / veya yatay olarak bağlanıp bağlanmadığını belirleyin.

Çıktı:

Bir truthy değeri tüm bağlı ise ve bir falsy değeri sıfır olmayan elemanları / başka elementlerle / gruplarla bağlı olmayan gruplar varsa.

Test senaryoları:

Test senaryoları satır ile ayrılır. Test senaryoları burada daha uygun formatlarda bulunabilir ( Kudos - Dada ).

Aşağıdakilerin hepsi bağlantılıdır ve gerçek bir değer döndürmelidir:

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

Aşağıdakilerin hepsi bağlı değildir ve bir sahte değer döndürmelidir:

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

Bu , bu yüzden her dilde en kısa teslim kazanmak kazanır. Açıklamalar teşvik edilir!


Bu meydan okumadan ilham alındı .


Belki de girdi, yalnızca bağlantılı bileşenlerle ilgili olduğundan yalnızca girişler ve sıfırlar (veya truthys ve falsys) içermelidir.
NikoNyrh

Girişi 1d dizisi ve birkaç sütun olarak alabilir miyiz?
ovs

@ovs emin. Zaten cevap veren diğer insanlara göre size herhangi bir avantaj sağlaması gerektiğini göremiyorum.
Stewie Griffin

2
İlgili : Tüm sıfır olmayan öğeleri birbirine bağlamak için kaç sıfıra ihtiyacınız var
dylnan

İlgili : bileşen sayısını sayın (ancak yan yana girişleri olan).
Misha Lavrov

Yanıtlar:


9

Retina 0.8.2 , 80 77 bayt

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

Çevrimiçi deneyin! Düzenleme: @FryAmTheEggman sayesinde 1 bayt kaydedildi. Açıklama:

T`d`@1

Bir @s ve 1s dizisini basitleştirin .

1`1
_

Birini bir 1ile değiştirin _.

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

Taşkın _bitişiğindeki 1s'ye doldurun .

^\D+$

Kalan olup olmadığını test edin 1.


@FryAmTheEggman Teşekkürler, ayrıca bana iki bayt daha nasıl kaydedeceğiniz konusunda bir fikir verdiniz!
Neil

7

JavaScript (ES6), 136 135 bayt

Bir boole döndürür.

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

Test senaryoları

Yorumlananlar

Özyinelemeli g () işlevi ilk olarak sıfır olmayan bir hücre arar (genel olarak tanımlanmış z bayrağı 0 olarak ayarlandığı sürece ) ve sonra oradan taşkın doldurmaya başlar ( 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 bayt

4&1ZI2<

Bu, doğruluk çıktısı olarak tümünü içeren bir matris veya falsi olarak en az sıfır içeren bir matris verir . Çevrimiçi deneyin!

Ayrıca , altbilgiye bir if- elseşube ekleyerek doğruluğu / sahteliği doğrulayabilirsiniz ; siz de deneyin!

Veya tüm test senaryolarını doğrulayın .

açıklama

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'nin notu: herhangi bir şüphe olması durumunda: çıktılar mükemmel derecede iyidir ve bağlantılı meta gönderiye yapışır.
Stewie Griffin

MATL / matlab'ın bir dizi sayıyı sıfır içermeyen doğru IFF olarak gördüğü aklımı başımdan alıyor. mathworks.com/help/matlab/ref/if.html (önceki yorum silindi)
Sparr

@Sparr (Aslında, sıfır içermiyorsa ve boş değilse .) Herhangi bir boş olmayan dizinin diğer dillerde doğru olduğunu öğrendiğimde de kafam karıştı
Luis Mendo


4

C, 163 bayt

İki bayt kaydettiği için @ user202729'a teşekkürler!

*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;}

Sıfır olmayan ilk öğeyi bulana kadar matriste dolaşır. Daha sonra bir süre döngüyü durdurur ve bulunan öğeye bağlı her sıfır olmayan öğeyi özyineli olarak sıfıra ayarlar. Ardından, her bir öğenin şimdi sıfır olup olmadığını kontrol ederek matrisin geri kalanında dolaşır.

Çevrimiçi deneyin!

unrolled:

*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 bayt

içerir +2için0a

Giriş matrisini STDIN üzerinde boşluk bırakmadan verin (veya aslında herhangi bir boşlukla ayrılmış satırlar olarak)

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

Bir dosyaya konulursa daha kolay okunur:

#!/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 bayt

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

Bu biraz zaman aldı, bu yüzden şimdi çalıştığına sevindim ..

Açıklama:

Çevrimiçi deneyin.

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

Jöle , 23 bayt

FJṁa@µ«Ḋoµ€ZUµ4¡ÐLFQL<3

Çevrimiçi deneyin!


Açıklama.

Program her bir morfolojik bileşeni farklı numaralarla etiketler, ardından 3'ten az sayı olup olmadığını kontrol edin. (dahil olmak üzere0 ).

Matristeki bir satırı düşünün.

«Ḋ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]

Bu işlevi matristeki tüm satır ve sütunlar için tüm sırayla uygulayın, sonunda tüm morfolojik bileşenler aynı etikete sahip olacaktır.

µ«Ḋ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.

Ve sonunda...

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.

Doğrusal zamanda yapabiliyorsanız hayali ödül. Bence Jelly'de bu mümkün değil, hatta ¦O (n) alır.
user202729

(tabii ki Python eval olmadan)
user202729

1

Haskell , 132 bayt

 \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

-dan çıkarıldı Hitori bulmaca çözme

indices m(line,cell)giriş ızgarasının konumlarını listeler .

filter((/=0).(m!)) sıfır olmayan değerlere sahip tüm konumları filtreler.

splitAt 1 ilk üyeyi dinlenme listesinin yanındaki tek bir liste halinde bölümler.

any(==1)[(b-d)^2+(p-q)^2|(d,q)<-f](b,p)sınıra dokunup dokunmadığını söyler f.

\(f,e)->partition(\(b,p)->touches(b,p)f)e henüz henüz temas etmeyenlerden dokunur.

until(null.fst)advanceFrontier sınır daha fazla ilerleyene kadar bunu tekrarlar.

null.snd sonuca ulaşılacak tüm yerlere gerçekten ulaşılıp ulaşılmadığını inceler.

Çevrimiçi deneyin!


1

Kir , 37 bayt

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

Eşleşecek 1ve eşleşmeyecek şekilde yazdırır 0. Çevrimiçi deneyin!

açıklama

Terminal dışı C, İngilizce okuma sırasında matrisin ilk sıfır olmayan karakterine bağlanan sıfır olmayan herhangi bir karakterle eşleşir.

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.

Bazı açıklamalar: egiriş matrisinin kenarının bir parçası olan sıfır genişlik veya yükseklikte bir dikdörtgenle eşleşir ve $herhangi bir şeyle eşleşen bir "joker karakter" dir. İfade e/\0{/e\0*0$eaşağıdaki gibi görselleştirilebilir:

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

İfade CoX^0oXaslında şu şekilde ayrıştırılır ((CoF)0)oX; oFve oXsonek operatörleri ve belirteçleri aracının birleştirme yatay birleştirme vardır. Yan ^yana yerleştirme daha yüksek bir öncelik verir oX, böylece döndürme tüm alt ifadeye uygulanır. oFYönünü düzeltir Cbu döndürülmüş sonra oX; aksi halde, döndürülmüş İngilizce okuma sırasında ilk sıfır olmayan koordinatla eşleşebilir.

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

Bu, tüm sıfır olmayan karakterlerin birincisine bağlanması gerektiği anlamına gelir. Izgara belirleyici :teknik olarak bir postfix operatörüdür, ancak C|:\0sözdizimsel şekerdir (C|\0):.


0

Perl 5 , 131129 + 2 ( -ap) = 133 bayt

push@a,[@F,0]}{push@a,[(0)x@F];$\=1;map{//;for$j(0..$#F){$b+=$a[$'][$j+$_]+$a[$'+$_][$j]for-1,1;$\*=$b||!$a[$'][$j];$b=0}}0..@a-2

Çevrimiçi deneyin!


0

Piton 2 , 211 163 , 150 bayt

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

Çevrimiçi deneyin!

Çıkış çıkış kodu ile yapılır. Girdi 1d listesi ve matrisin genişliği gibidir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.