Xóa các số 0 xung quanh của mảng 2d


40

Đây là phiên bản 2 chiều của câu hỏi này .

Cho một mảng / ma trận 2 chiều không trống chỉ chứa các số nguyên không âm:

[0000000010000010011100000]

Xuất ra mảng với các số 0 xung quanh bị loại bỏ, tức là phân đoạn tiếp giáp lớn nhất mà không có các số 0 xung quanh:

[010001111]

Ví dụ:

[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 Không có gì là khó khăn trong một ngôn ngữ không bí truyền. :)Chỉ khó để làm cho nó ngắn.
dùng202729

1
Chúng ta có thể đưa ra một đầu ra falsey thay vì một ma trận trống, cho trường hợp thử nghiệm cuối cùng không?
- Phục hồi Monica

1
Ngoài ra, nếu đầu ra có thể là một ma trận không vuông, vui lòng thêm một trường hợp thử nghiệm cho điều đó.
- Phục hồi Monica

1
Một trường hợp thử nghiệm đã phá vỡ nội dung gửi trước đó của tôi: [[0, 0, 0, 0], [0, 0, 0, 0], [1, 1, 1, 1], [0, 0, 0, 0]](kết quả có chiều rộng / chiều cao 1)
Conor O'Brien

1
Xin chào, có thể thêm trường hợp thử nghiệm
[111112311111]
Decay Decay

Câu trả lời:



39

Ngôn ngữ Wolfram (Mathicala) , 42 byte

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

Hãy thử trực tuyến!

Cellata automata thực sự là câu trả lời cho cuộc sống , vũ trụtất cả mọi thứ . 1

Làm sao?

CellularAutomatonchấp nhận một mảng đầu vào và một giá trị nền tùy chọn. Do đó, {#,0}xác định rằng một quy tắc tự động di động nên được áp dụng cho đầu vào, giả sử một nền tảng của 0s.

Một điều gọn gàng ở đây là cắt CellularAutomatonđầu ra sao cho không có đường viền của các ô nền (vì nếu không thì đầu ra nằm trên một mặt phẳng vô hạn).

Mã áp dụng quy tắc {Null, {}, {0, 0}}- áp dụng đầu Nullcho hàng xóm 0 bán kính của mỗi ô (tức là chỉ trung tâm: chính ô) - chính xác 0lần. Kết quả của việc này là đầu vào ban đầu, nhưng đã bị xóa nền (tức là cắt xén xung quanh 0s).


1. Xem phần phụ của câu trả lời của tôi? ;)


6
Lạm dụng nội dung tốt đẹp ... cũng Mathicala có tích hợp sẵn, chỉ không được tiếp xúc trực tiếp.
dùng202729

3
Không có tài liệu tham khảo XKCD 505 ?
Esolanging Fruit 30/07/18

+1 cho Cellular Automata & Câu trả lời cuối cùng.
Đánh giá cao

14

JavaScript (ES6), 98 byte

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

Hãy thử trực tuyến!

Làm sao?

Để khắc phục việc thiếu zip tích hợp, chúng tôi xác định hàm g () có thể hoạt động trên các hàng hoặc cột của ma trận đầu vào a [] , tùy thuộc vào giá trị của cờ toàn cầu z .

g () tìm kiếm chỉ số tối thiểu m và chỉ số tối đa M của các hàng không trống (nếu z không xác định) hoặc các cột không trống (nếu z được xác định) và trả về lát tương ứngcủa chính ma trận hoặc một hàng nhất định của ma trận.

Để tóm tắt:

  • đầu tiên chúng ta xóa các hàng bằng cách gọi g () trên ma trận với z không xác định
  • sau đó chúng tôi xóa các cột bằng cách gọi g () trên mỗi hàng với z được xác định, dẫn đến điều này khá bất thường.map(z=g)

Đã bình luận

(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
Thật ấn tượng.
Jack Hales

3
@Jek, Arnauld sống ở một chiều hoàn toàn khác. Nhưng nếu bạn cực kỳ may mắn, thỉnh thoảng bạn có thể tìm thấy một mẹo mà anh ấy đã bỏ lỡ và đăng một giải pháp ngắn hơn. Trong quá trình này, bạn sẽ phát triển sự hiểu biết rất sâu sắc về JavaScript.
Rick Hitchcock

4
@RickHitchcock Tôi không giỏi nhận dạng mẫu mã và tôi thường xuyên thiếu rất nhiều thứ, ngay cả khi tôi đã nhìn thấy chúng trước đây. Trong ví dụ cụ thể này, tôi đã tập trung vào khả năng sử dụng lại của g () và đã bỏ lỡ khá tối ưu hóa rõ ràng trên đường cập nhật mM (-9 byte). Tôi hoàn toàn đồng ý rằng chơi golf mã là một cách tuyệt vời (và thú vị) để tìm hiểu nhiều về sự tinh tế của ngôn ngữ.
Arnauld

7

Haskell , 62 61 byte

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

Hãy thử trực tuyến!

foldr(zipWith(:))evới e=[]:elà một chút ngắn hơntranspose , và snd.span(all(<1))giảm danh sách số không hàng đầu từ một danh sách danh sách. Theo transposesau reversetrong danh sách 2D bằng với góc quay 90 °, mã f.f.f.fchỉ là bốn lần thả danh sách số 0 và xoay hàng đầu .




5

Brachylog , 24 22 20 19 byte

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

Hãy thử trực tuyến!

Xuất ra ma trận kết quả dưới dạng một mảng các mảng hoặc sai cho đầu ra trống.

(Cảm ơn @Firthize đã đề xuất vị ngữ nội tuyến và tiết kiệm 1 byte.)

Giải trình

Vị ngữ 0 (Chính):

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

Vị ngữ 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)

Viết nội tuyến vị ngữ đầu tiên ngắn hơn 1 byte : {s.h+>0∧.t+>0∧}\↰₁\ . (điều này đúng với hầu hết mọi câu trả lời của Brachylog, các vị từ trên các dòng mới thực sự chỉ được thực hiện nếu bạn muốn viết những thứ dễ đọc hơn).
Gây tử vong vào

@Firthize Cảm ơn, cập nhật (cuối cùng!). Tôi chưa bao giờ nghĩ về cách cú pháp vị ngữ nội tuyến là cả một ứng dụng định nghĩa và vị ngữ, khá tuyệt.
- Phục hồi lại

5

R , 96 100 97 byte

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

Hãy thử trực tuyến!

Người ~trợ giúp lấy một vectơ không âm và trả về một vectơ với FALSE"bên ngoài" 0của vectơ và TRUEcho dương và bất kỳ "bên trong" nào 0. Hàm này được áp dụng cho các tổng hàng và cột của ma trận đầu vào.

~! sử dụng trình xử lý phân tích cú pháp của R của các toán tử.

Đã sửa theo nhận xét của @ DigEmAll, nhưng với một số byte được lấy lại từ @ J.Doe


1
Tôi nghĩ bạn nên thêm drop=Fnhư tôi đã làm, nếu không 2 bài kiểm tra này sẽ trả về một vectơ thay vì hàng và cột: Hãy thử trực tuyến!
digEmAll

97 byte với drop=F. Vẫn dưới một tấn!
J.Doe

5

R , 89 79 byte

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

Hãy thử trực tuyến!

Cảm ơn @ngm về mã trường hợp thử nghiệm và @ J.Doe vì đã lưu 10 byte!

  • Tôi đã phải thêm drop=Ftham số do hành vi R mặc định biến ma trận hàng / col đơn thành vectơ ...

Tôi đã không nhận thấy rằng mã trước đây của tôi đã thất bại trong các trường hợp hoàn toàn bằng không ... bây giờ nó đã được sửa một cách đáng tiếc với nhiều byte hơn :(
digEmAll

1
Tôi ước tôi có thể +2 cái này. Sử dụng thực sự tốt đẹp của fivenum.
JayCe

79 byte sử dụng rangevà điều chỉnh chỉ mục
J.Doe

1
@ J.Doe: phạm vi, tất nhiên! ý tưởng tuyệt vời cảm ơn!
digEmAll






2

Husk , 11 byte

!5¡(T0mo↔↓¬

Hãy thử trực tuyến!

Tôi cảm thấy như một số byte có thể được loại bỏ bằng cách rút ngắn !5¡phần.

Làm thế nào nó hoạt động

!5¡(

5th

mo↔↓¬

Ánh xạ qua phiên bản hiện tại của đầu vào và: đảo ngược từng cái, sau khi đã loại bỏ tiền tố dài nhất chỉ sử dụng số 0 (loại bỏ tiền tố này được thực hiện bằng cách sử dụng Husk , đây là chức năng cắt các phần tử liên tiếp dài nhất từ ​​đầu danh sách mang lại kết quả trung thực khi chạy qua một hàm, cụ thể là ¬logic không).

T0

Chuyển đổi, thay thế các mục bị thiếu bằng 0 .


2

Võng mạc , 87 byte

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

Hãy thử trực tuyến! Giải trình:

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

Cho đến khi ít nhất một hàng không bắt đầu bằng 0 ...

\[0, 
[

... loại bỏ số 0 đứng đầu từ mỗi hàng.

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

Cho đến khi ít nhất một hàng không kết thúc bằng 0 ...

, 0]
]

... xóa số 0 ở mỗi hàng.

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

Loại bỏ các hàng đầu của số không.

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

Xóa các hàng số 0 ở cuối hoặc số 0 còn lại cuối cùng.


1
@RickHitchcock Định dạng nhạy cảm, thêm vào khoảng trắng: Hãy thử trực tuyến!
Neil

2

Than , 48 byte

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

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã. Bao gồm 15 byte để định dạng. Giải trình:

F⁴«

Lặp lại 4 lần.

W∧θ¬Σ§θ±¹

Lặp lại trong khi mảng không trống nhưng hàng cuối cùng của nó bằng không ...

Σ⊟θ

Xóa hàng cuối cùng khỏi mảng và in một dòng có độ dài của tổng của nó, tức là không có gì.

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

Nếu mảng không trống thì hoán vị nó.

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

Định dạng mảng độc đáo để hiển thị. (Đầu ra tiêu chuẩn sẽ được Iθthay thế.)


2

JavaScript, 144 140 129 127 byte

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 byte, cảm ơn @Arnauld

Thuật toán

  • Làm hai lần:
    • Tìm hàng khác không đầu tiên
    • Cắt các hàng trước
    • Đảo ngược
    • Tìm hàng khác không đầu tiên
    • Cắt các hàng trước
    • Đảo ngược
    • Chuyển

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


Bạn có thể lưu 7 byte bằng cách sử dụng some/somethay vì findIndex/findvà sắp xếp lại các khai báo hàm trợ giúp để thoát khỏi dấu ngoặc đơn xung quanh đối số hàm chính (bây giờ là đơn).
Arnauld

Tôi nghĩ rằng bạn có thể tiết kiệm nhiều hơn 4 byte bằng cách s trở lại [[]]để t được đảm bảo để có thể hoạt động trên w[0].
Arnauld

2

Python 2 , 118 116 byte

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

Hãy thử trực tuyến!


Đã lưu:

  • -2 byte, nhờ shooqie

1
Bạn có thể lưu hai byte bằng cách gán s=sumtrong định nghĩa lambda
shooqie

2

PHP (> = 5,4), 200 194 186 184 byte

(-6 byte bằng cách trả về nullthay vì mảng trống)

(-8 byte nhờ Tít )

(-2 byte với cách gọi bằng tham chiếu nhờ Titus )

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

Hãy thử trực tuyến!

Làm sao?

Tìm chỉ số tối thiểu và tối đa cho các hàng ( $m& $M) và cột ( $n& $N) và thay thế đầu vào bằng một mảng phụ từ $m,$nđến $M,$N(đây là một cuộc gọi theo tham chiếu).


Lưu 6 byte vớiif($C){$m>$r&&$m=$r;$M>$r||$M=$r;$n>$c&&$n=$c;$N>$c||$N=$c;}
Titus

... và hai byte vớiwhile($m<=$M)$o[]=array_slice($a[$m++],$n,$N-$n+1);
Titus

@Titus: Cảm ơn những lời khuyên tuyệt vời. Yêu thích thủ thuật sử dụng &&||tôi chắc chắn tôi cũng sẽ có thể sử dụng thủ thuật đó ở những nơi khác.
Đêm2

1
Bạn có thể lưu hai byte khác bằng cuộc gọi bằng cách tham chiếu: $a=thay vì return.
Tít

2

Octave, 48 49 byte

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

Hãy thử trực tuyến!

Tìm các điểm khác không và sắp xếp lại chúng trong một ma trận thưa thớt mới.


@alephalpha Trả lời cập nhật!
rahnema1


2

J , 24 byte

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

Hãy thử trực tuyến!

Giải trình

(|.@|:@}.~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 byte

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

Hãy thử trực tuyến!

Chỉnh sửa: đơn giản hóa, cũng là phiên bản trước bị lỗi cho tất cả 0s

Làm thế nào nó hoạt động:

  • làm 4 lần:
    • xóa dòng đầu tiên trong khi có dòng đầu tiên và nó đầy 0s
    • xoay mảng theo chiều kim đồng hồ 90 °
  • trả về mảng

Liên kết là chính xác, nhưng câu trả lời của bạn trong khối mã nói &.sum<0thay vì &.sum<1.
Conor O'Brien

@ ConorO'Brien phiên bản mới, xấu của tôi không hoạt động cho mảng trống (nil <1). Dù sao cũng cảm ơn vì đã chú ý
Asone Tuhid

1

Octave , 78 74 byte

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

Hãy thử trực tuyến!

Giải trình

Điều này xoay ma trận theo 90độ ( x=rot90(x)) một số lần đủ ( for k=1:... end). Số lượng phép quay là bội số của 4, vì vậy ma trận cuối cùng có hướng ban đầu. Cụ thể, số lần quay bằng số 4lần số không trong ma trận ( nnz(~x)*4).

Đối với mỗi vòng quay, nếu có một hoặc nhiều cột ở bên trái chỉ bao gồm các số 0 thì chúng sẽ bị xóa ( x=x(:,~~cumsum(any(x,1)))).

Phần còn lại của ma trận sau quá trình này là đầu ra của hàm ( function x=f(x)).



1

PHP, 188 byte

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

gọi bằng cách tham khảo.

phá vỡ

// 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 byte

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]

Hãy thử trực tuyến!

Đưa ra một danh sách các danh sách, trả về một danh sách các bộ dữ liệu.

Giải trình

Lạm dụng quái vật ra khỏi danh sách hiểu. Đây là mã mở rộng tương đương:

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 byte

4Æ=sUb_dà z

Thử nó


Giải trình

                :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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.