2d dizisinin çevreleyen sıfırlarını kaldırın


40

Bu, bu sorunun 2 boyutlu bir versiyonudur .

Yalnızca negatif olmayan tamsayılar içeren boş olmayan bir 2 boyutlu dizi / matris verildiğinde:

[0000000010000010011100000]

Çevreleyen sıfırlar kaldırılmış diziyi, yani çevreleyen sıfırlar içermeyen en büyük bitişik alt diziyi çıktılayın:

[010001111]

Örnekler:

[0000000010000010011100000][010001111]
Input:
[[0, 0, 0, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1], [0, 0, 1, 1, 1], [0, 0, 0, 0, 0]]

Output:
[[0, 1, 0], [0, 0, 1], [1, 1, 1]]

[00000003000005000000][003000500]
Input:
[[0, 0, 0, 0], [0, 0, 0, 3], [0, 0, 0, 0], [0, 5, 0, 0], [0, 0, 0, 0]]

Output:
[[0, 0, 3], [0, 0, 0], [5, 0, 0]]

[123456789][123456789]
Input:
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

Output:
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

[000000000000][]
Input:
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

Output:
[]

[000011110000][1111]
Input:
[[0, 0, 0, 0], [1, 1, 1, 1], [0, 0, 0, 0]]

Output:
[[1, 1, 1, 1]]

[010001000100][111]
Input:
[[0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0]]

Output:
[[1], [1], [1]]

[111112311111][111112311111]
Input:
[[1, 1, 1, 1], [1, 2, 3, 1], [1, 1, 1, 1]]

Output:
[[1, 1, 1, 1], [1, 2, 3, 1], [1, 1, 1, 1]]

3
@MattH Ezoterik olmayan bir dilde hiçbir şey zor değildir. :)Kısa yapmak zor.
user202729

1
Son test durumu için boş bir matris yerine bir yanlış sonuç verebilir miyiz?
sundar - Reinstate Monica,

1
Ayrıca, çıktı kare olmayan bir matris olabilirse, lütfen bunun için bir test durumu ekleyin.
sundar - Reinstate Monica

1
Daha önceki başvurumu bozan bir test davası: [[0, 0, 0, 0], [0, 0, 0, 0], [1, 1, 1, 1], [0, 0, 0, 0]](sonuç genişlik / yüksekliğe 1
Conor O'Brien,

1
Hey, sınama durumu
[111112311111]
Beta Decay

Yanıtlar:



39

Wolfram Dili (Mathematica) , 42 bayt

#&@@CellularAutomaton[{,{},0{,}},{#,0},0]&

Çevrimiçi deneyin!

Hücresel otomatlar aslında hayata , evrene ve her şeye cevaptır . 1

Nasıl?

CellularAutomatonbir giriş dizisini ve isteğe bağlı bir arka plan değerini kabul eder. Bu nedenle, {#,0}hücresel bir otomat kuralının, 0s'nin arkaplanı olduğu varsayılarak girdiye uygulanması gerektiğini belirtir .

Buradaki en güzel şey CellularAutomaton, çıktının arka plan hücrelerinin sınırının olmaması için kesilmesidir (çünkü çıktı sonsuz bir düzlemde uzanır).

Kod kuralı uygular {Null, {}, {0, 0}}- kafayı Nullher hücrenin 0 yarıçaplı komşusuna uygular (yani yalnızca merkez: hücrenin kendisi) - tam olarak 0. Bunun sonucu asıl girdidir, fakat arkaplan kaldırılmıştır (yani çevreleyen alanları kırparak 0).


1. Cevabımın bayt sayısını görüyor musunuz? ;)


6
Güzel yerleşik kötüye kullanım ... iyi Mathematica'nın yerleşik, doğrudan gösterilmeyen.
user202729

3
XKCD 505 referansı yok mu?
Esolanging Fruit,

Hücresel Otomatlar ve Nihai Cevap için +1.
HighRadioactive

14

JavaScript (ES6), 98 bayt

(a,z)=>(g=A=>A.slice(A.map(m=M=(r,i)=>M=(z?a:r).some(n=>z?n[i]:n)?1/m?i:m=i:M)|m,M+1))(a).map(z=g)

Çevrimiçi deneyin!

Nasıl?

Bir yerleşik zip eksikliğinin üstesinden gelmek için , küresel bayrak z'nin değerine bağlı olarak giriş matrisinin a [] satırlarında veya sütunlarında çalışabilen g () işlevini tanımlarız .

g () en az endeks arar, m ve maksimum indeksi M ya boş olmayan sıralarının (eğer z tanımlanmamış) ya da boş olmayan sütunlar (eğer z tanımlandığı gibidir) ve döner gelen dilim matrisin kendisi ya da belirli bir satır ya Matris

Özetlemek:

  • önce z undefined ile matriks üzerindeki g () 'yi çağırarak satırları kaldırdık
  • daha sonra , her bir sıradaki g () 'yi z' yi çağırarak çağırarak sütunları kaldırıyoruz ;.map(z=g)

Yorumlananlar

(a, z) => (               // a[] = input matrix; z is initially undefined
  g = A =>                // g() = function taking A = matrix or row
    A.slice(              //   eventually return A.slice(m, M + 1)
      A.map(m = M =       //     initialize m and M to non-numeric values
        (r, i) =>         //     for each row or cell r at position i in A:
        M = (z ? a : r)   //       iterate on either the matrix or the row
        .some(n =>        //       and test whether there's at least one
          z ? n[i] : n    //       non-zero cell in the corresponding column or row
        ) ?               //       if so:
          1 / m ? i       //         update the maximum index M (last matching index)
                : m = i   //         and minimum index m (first matching index)
        :                 //       otherwise:
          M               //         let M (and m) unchanged
      ) | m,              //     end of map(); use m as the first parameter of slice()
      M + 1               //     use M+1 as the second parameter of slice()
    )                     //   end of slice()
  )(a)                    // invoke g() on the matrix with z undefined
  .map(z = g)             // invoke g() on each row of the matrix with z defined

2
Bu etkileyici.
Jack Hales

3
@Jek, Arnauld bambaşka bir boyutta yaşıyor. Fakat eğer çok şanslıysanız, zaman zaman kaçırdığı ve daha kısa bir çözüm yolladığı bir numara bulabilirsiniz. Süreçte, çok derin bir JavaScript anlayışı geliştireceksiniz.
Rick Hitchcock

4
@RickHitchcock Kod örüntü tanıma konusunda o kadar iyi değilim ve daha önce görmüş olsam bile, düzenli olarak birçok şeyi özlüyorum. Bu özel örnekte, g () 'nin tekrar kullanılabilirliğine odaklandım ve m ve M (-9 bayt)' ları güncelleme yolunda oldukça belirgin bir optimizasyondan kaçındım. Kod golfünün bir dilin inceliklerini hakkında çok şey öğrenmenin harika (ve eğlenceli) bir yol olduğuna tamamen katılıyorum.
Arnauld,

7

Haskell , 62 61 bayt

f.f.f.f
f=reverse.foldr(zipWith(:))e.snd.span(all(<1))
e=[]:e

Çevrimiçi deneyin!

foldr(zipWith(:))eile e=[]:ea, biraz daha kısatranspose ve snd.span(all(<1))listenin bir listeden sıfır gelen listeleri düşer. Bir 2B listesinde transposeizlediği gibi reverse, 90 ° 'lik bir dönüşe eşittir, kod f.f.f.fyalnızca dört kere sıfır önde gelen listelerden oluşur ve döner .




5

Brachylog , 24 22 20 19 bayt

{s.h+>0∧.t+>0∧}\↰₁\

Çevrimiçi deneyin!

Sonuç matrisini bir dizi dizisi olarak veya boş çıktı için false olarak verir.

(Satır içi yüklemi öneren ve 1 bayt tasarrufu önerdiği için @Fatalize'e teşekkürler.)

açıklama

Tahmini 0 (Ana):

{...}     Define and call predicate 1 to remove all-zero rows
  \       Transpose the result
   ↰₁     Call pred 1 again, now to remove all-zero columns
     \    Transpose the result to have correct output orientation

Tahmin 1:

?s.h+>0∧.t+>0∧
  .           output is
 s              a subsequence of the rows of
?              the input (implicit)
   h          also, output's head element (first row)
    +>0        has a sum > 0 (i.e. has at least one non-zero value)
       ∧.t+>0  and similarly the output's tail element (last row)
∧              (don't implicitly unify that 0 with the output)

İlk yüklem inline Yazma 1 bayt kısadır: {s.h+>0∧.t+>0∧}\↰₁\ . (Bu hemen hemen herhangi bir Brachylog cevabı için geçerlidir, yeni satırlardaki tahminlerin gerçekten daha okunaklı şeyler yazmak istediğinizde uygulandığını tahmin eder).
18'de

@Fatalize Teşekkürler, güncellendi (nihayet!). Satır içi öngörme sözdiziminin hem tanım hem de yordam uygulaması olduğunu hiç düşünmedim, oldukça havalı.
sundar - Monica,

5

R , 96 100 97 bayt

function(m)m[~m,~t(m),drop=F]
"~"=function(x,z=seq(r<-rowSums(x)))z>=min(y<-which(r>0))&z<=max(y)

Çevrimiçi deneyin!

~Yardımcı negatif olmayan bir vektör ve getiri ile bir vektör alır FALSE"dış" için 0vektör s ve TRUEpozitifler ve herhangi bir "iç" için 0s. Bu işlev giriş matrisinin satır ve sütun toplamlarına uygulanır.

~ve ! R'nin operatörlerin ayrıştırıcı muamelesini kullanın.

@ DigEmAll'ın yorumuna göre düzeltildi, ancak bazı baytlar @ J.Doe'dan geri golf oynadı


1
Benim drop=Fyaptığım gibi eklemelisin , aksi takdirde bu 2 test satır ve sütun yerine bir vektör döndürür: Çevrimiçi deneyin!
digEmAll

97 bayt ile drop=F. Hala bir tonun altında!
J.Doe

5

R , 89 79 bayt

function(m,y=apply(which(m>0,T),2,range)){y[!1/y]=0;m[y:y[2],y[3]:y[4],drop=F]}

Çevrimiçi deneyin!

Test durumları kodu için @ ngm ve 10 byte tasarruf için @ J.Doe!

  • drop=FTek satır / sütun matrisini vektörlere çeviren varsayılan R davranışı nedeniyle parametre eklemek zorunda kaldım ...

Önceki
kodumun

1
Keşke bunu + 2 yapabilseydim. Fivenum'un gerçekten güzel kullanımı.
JayCe

rangeEndekslemeyi kullanan ve değiştiren 79 bayt
J.Doe

1
@ J.Doe: aralığı, elbette! harika bir fikir teşekkürler!
digEmAll


3

Python 2 , 71 bayt

Girişi değiştirerek döndürür. Giriş olarak bir liste iletilmelidir.

def f(a):exec'while a and 1>sum(a[-1]):a.pop()\na[:]=zip(*a)[::-1]\n'*4

Çevrimiçi deneyin!


Python 2,77 bayt

Bu aynı zamanda girişi de değiştirir, ancak çalışır.

def f(a):exec'while a and 1>sum(a[-1]):a.pop()\na=zip(*a)[::-1]\n'*4;return a

Çevrimiçi deneyin!





2

Kabuğu , 11 bayt

!5¡(T0mo↔↓¬

Çevrimiçi deneyin!

Parçayı kısaltarak bazı baytların traşlanabileceğini hissediyorum !5¡.

Nasıl çalışır

!5¡(

5inci

mo↔↓¬

Girişin geçerli sürümü üzerinde eşleyin ve: her birini ters çevirin, yalnızca sıfırdan oluşan en uzun ön eki bıraktıktan sonra (bu ön eki bırakma , üst üste en uzun arka arkaya gelen öğeleri kesen bir işlev olan Husk's kullanılarak gerçekleştirilir . Bir işlevden geçirildiğinde, yani ¬mantıksal değilken , truthy sonuçlarını veren liste .

T0

Transpose, eksik olanları 0 ile değiştir .


2

Retina , 87 bayt

/.\[(?!0,)/^+`\[0, 
[
/(?<! 0)]./^+`, 0]
]
\[(\[0(, 0)*], )+
[
(, \[0(, 0)*])+]|\[0]]
]

Çevrimiçi deneyin! Açıklama:

/.\[(?!0,)/^+`

En az bir satır sıfıra gelinceye kadar ...

\[0, 
[

... her satırdaki baştaki sıfırı kaldır.

/(?<! 0)]./^+`

En az bir satır sıfır ile bitinceye kadar ...

, 0]
]

... her sıradaki son sıfırı kaldırın.

\[(\[0(, 0)*], )+
[

Baştaki sıfır satırlarını kaldırın.

(, \[0(, 0)*])+]|\[0]]
]

Sondaki sıfır sırasını veya kalan son sıfırı kaldırın.


1
@RickHitchcock Biçime duyarlıdır, boşluklara ekleyin: Çevrimiçi deneyin!
Neil,

2

Kömür , 48 bayt

F⁴«W∧θ¬Σ§θ±¹Σ⊟θ¿θ≔⮌E§θ⁰E觧θνλθ»⪫[]⪫Eθ⪫[]⪫ι, ¦, 

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı bir versiyonudur. Biçimlendirme için 15 bayt içerir. Açıklama:

F⁴«

4 kez tekrarlayın.

W∧θ¬Σ§θ±¹

Dizi boş değilken tekrarlayın, ancak son satır sıfıra geliyor ...

Σ⊟θ

Diziden son satırı çıkarın ve toplam uzunluğunun bir satırını, yani hiçbir şeyi yazdırmayın.

¿θ≔⮌E§θ⁰E觧θνλθ»

Dizi boş değilse, onu dönüştürün.

⪫[]⪫Eθ⪫[]⪫ι, ¦, 

Diziyi ekran için güzelce biçimlendirin. ( IθBunun yerine standart çıktı olur .)


2

JavaScript, 144 140 129 127 bayt

w=>(t=w=>(q=(s=w=>w.some((r,j)=>r.find(e=>e,i=j))?w.slice(i).reverse():[[]])(s(w)))[0].map((e,j)=>q.map((e,i)=>q[i][j])))(t(w))

140 -> 129 bayt, teşekkürler @Arnauld

Algoritma

  • İki kez yap:
    • İlk sıfır olmayan satırı bul
    • Önceki satırlardan dilimleme
    • Ters
    • İlk sıfır olmayan satırı bul
    • Önceki satırlardan dilimleme
    • Ters
    • Transpoze

f = w=>(t=w=>(q=(s=w=>w.some((r,j)=>r.find(e=>e,i=j))?w.slice(i).reverse():[[]])(s(w)))[0].map((e,j)=>q.map((e,i)=>q[i][j])))(t(w));

w1 = [[0, 0, 0, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1], [0, 0, 1, 1, 1], [0, 0, 0, 0, 0]];
w2 = [[0, 0, 0, 0], [0, 0, 0, 3], [0, 0, 0, 0], [0, 5, 0, 0], [0, 0, 0, 0]];
w3 = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
w4 = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]];

console.log(f(w1).join("\n"));
console.log(f(w2).join("\n"));
console.log(f(w3).join("\n"));
console.log(f(w4));


Sen edebilirsiniz 7 bayt kaydetmek kullanarak some/someyerine findIndex/findve (şimdi tek) ana işlevi argüman etrafında parantez kurtulmak için yardımcı işlevi bildirimleri yeniden düzenleme.
Arnauld,

Ben düşünüyorum yapabilirsiniz 4 daha bayt kaydetmek suretiyle ler dönüşü [[]]böylece t üzerinde işlem yapabilmek için garanti edilir w[0].
Arnauld,

2

Python 2 , 118 116 bayt

f=lambda a,n=4,s=sum:n and f(zip(*a[max(i for i in range(len(a))if s(s(a[:i],()))<1):][::-1]),n-1)or(s(s(a,()))>0)*a

Çevrimiçi deneyin!


Kaydedilen:

  • -2 bayt, shooqie sayesinde

1
s=sumLambda tanımını atayarak iki bayttan tasarruf edebilirsiniz
shooqie

2

PHP (> = 5.4), 200 194 186 184 bayt

( nullBoş dizi yerine döndürerek -6 bayt )

( Titus sayesinde -8 bayt )

( Titus sayesinde referans ile arayarak -2 bayt )

function R(&$a){$m=$n=1e9;foreach($a as$r=>$R)foreach($R as$c=>$C)if($C){$m>$r&&$m=$r;$M>$r||$M=$r;$n>$c&&$n=$c;$N>$c||$N=$c;}for(;$m<=$M;)$o[]=array_slice($a[$m++],$n,$N-$n+1);$a=$o;}

Çevrimiçi deneyin!

Nasıl?

Bulur dakika ve sıra (max indeksi $mve $M) ve sütunlar ( $nve $Nelde edilmiş) ve yerine geçer, bir alt dizisiyle giriş $m,$niçin $M,$N(bu, referans ile bu bir çağrıdır).


6 bayttan if($C){$m>$r&&$m=$r;$M>$r||$M=$r;$n>$c&&$n=$c;$N>$c||$N=$c;}
Titus

... ve iki bayt ilewhile($m<=$M)$o[]=array_slice($a[$m++],$n,$N-$n+1);
Titus

@Titus: Harika ipuçları için teşekkürler. Kullanma hilesini sevdi &&ve ||bu numarayı başka yerlerde de kullanabileceğime eminim.
Gece2,

1
Başka bir iki byte'ı referans ile çağrı yaparak kaydedebilirsiniz: $a=bunun yerine return.
Titus,

2

Octave, 48 49 bayt

@(a)sparse(1-min([x y v]=find(a))+x,1-min(y)+y,v)

Çevrimiçi deneyin!

Sıfır olmayan noktaları bulun ve bunları yeni bir seyrek matriste yeniden düzenleyin.


@alephalpha Yanıt güncellendi!
rahnema1


2

J , 24 bayt

(|.@|:@}.~0=+/@{.)^:4^:_

Çevrimiçi deneyin!

açıklama

(|.@|:@}.~0=+/@{.)^:4^:_
            +/                sum
              @               of
               {.             the first row
          0=                  is zero? (1 = true, 0 = false)
       }.~                    chop off that many rows from the front
 |.@|:@                       rotate by 90 deg (transpose then reverse)
(                )^:4         repeat this process 4 times (rotating a total of 360 deg)
                     ^:_      fixpoint - repeat until no change

2

Ruby , 73 63 bayt

->a{4.times{_,*a=a while a[0]&.sum==0;a=a.reverse.transpose};a}

Çevrimiçi deneyin!

Düzenleme: basitleştirilmiş, önceki sürüm tüm 0s için düştü

Nasıl çalışır:

  • 4 kez yapın:
    • ilk satırı kaldırırken ilk satırı kaldır ve 0s dolu
    • diziyi saat yönünde 90 ° döndür
  • diziyi döndür

Bağlantı doğrudur, ancak kod bloğundaki cevabınız &.sum<0bunun yerine der &.sum<1.
Conor O'Brien,

@ ConorO'Brien benim kötü, yeni sürüm boş dizi (nil <1) için işe yaramadı. Yine de fark ettiğiniz için teşekkürler
Asone Tuhid

1

Octave , 78 74 bayt

function x=f(x)
for k=1:nnz(~x)*4,x=rot90(x);x=x(:,~~cumsum(any(x,1)));end

Çevrimiçi deneyin!

açıklama

Bu matrisi 90derece ( x=rot90(x)) yeterli sayıda ( ) döndürür for k=1:... end. Dönme sayısı bir katıdır 4, yani son matris orijinal oryantasyona sahiptir. Spesifik olarak, dönüşlerin 4sayısı matris ( nnz(~x)*4) içindeki sıfırların sayısıdır .

Her döndürme için, solda yalnızca sıfırdan oluşan bir veya daha fazla sütun varsa, bunlar kaldırılır ( x=x(:,~~cumsum(any(x,1)))).

Bu işlemden sonra matrisin kalan kısmı, ( function x=f(x)) işlevi tarafından verilir .



1

PHP, 188 bayt

function f(&$a){for($s=array_shift;!max($a[0]);)$s($a);for($p=array_pop;!max(end($a));)$p($a);for($w=array_walk;!max(($m=array_map)(reset,$a));)$w($a,$s);while(!max($m(end,$a)))$w($a,$p);}

referans ile arayın.

Yıkmak

// call by reference
function f(&$a)
{
    // while first row is all zeroes, remove it
    while(!max($a[0]))array_shift($a);
    // while last row is all zeroes, remove it
    while(!max(end($a)))array_pop($a);
    // while first column is all zeroes, remove it
    while(!max(array_map(reset,$a)))array_walk($a,array_shift);
    // while last column is all zeroes, remove it
    while(!max(array_map(end,$a)))array_walk($a,array_pop);
}


1

Python 2,86 bayt

lambda a,l=1:a if l>4else([a.pop()for b in a if sum(a[-1])<1],f(zip(*a[::-1]),l+1))[1]

Çevrimiçi deneyin!

Listelerin bir listesini alır, bir listenin listesini döndürür.

açıklama

Liste dışı kavrama hilelerini kötüye kullanır. Bu eşdeğer genişletilmiş koddur:

def f(a,l=1):
    # after 4 rotations, the list is back in its original orientation, return
    if l > 4:
        return a
    else:
        # helper variable to store return values
        ret = []
        # "trim" all rows from "bottom" of list that only contain 0s
        # since we are always checking le that item in the list, don't need range(len(a))
        # since we are only removing at most one item per iteration, will never try to remove more than len(a) items
        # brackets surrounding generator force it to be consumed make a list, and therefore actually pop() list items
        ret.append([a.pop() for b in a if sum(a[-1]) < 1])
        # rotate the array, increase the number of rotations, and recursively call this function on the new array/counter
        ret.append(f(zip(*a[::-1]), l + 1)))
        # we only put both items in a list in order to stay in the one-line lambda format
        # discard the popped items and return the value from the recursive call
        return ret[1]

1

Japt -h , 23 11 bayt

4Æ=sUb_dà z

Dene


açıklama

                :Implicit input of 2D-array U
4Æ              :Map the range [0,4)
   s            :  Slice U from
    Ub          :   The first index in U where
      _dà      :    Any element is truthy (not zero)
          z     :  Rotate 90 degrees
  =             :  Reassign to U for the next iteration
                :Implicitly output the last element
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.