Cẩn thận với cơn lốc xoáy ma trận!


27

Lốc xoáy ma trận cũng giống như bất kỳ cơn lốc xoáy nào khác: nó bao gồm những thứ xoay quanh một trung tâm. Trong trường hợp này, các yếu tố của ma trận thay vì không khí.

Dưới đây là một ví dụ về cơn lốc xoáy ma trận:

Ma trận lốc xoáy trong hành động

Đầu tiên chúng ta bắt đầu bằng cách chia ma trận thành các vòng vuông, mỗi phần bao gồm các phần tử nằm cách xa biên giới hơn cùng một khoảng cách. Những phần này sẽ được xoay theo chiều kim đồng hồ xung quanh trung tâm. Trong các cơn lốc xoáy thực sự, mức độ nghiêm trọng tăng dần về phía trung tâm, và bước xoay trong cơn lốc xoáy ma trận cũng vậy: phần ngoài cùng (phần màu đỏ) được xoay 1 bước, phần tiếp theo (màu vàng) được xoay bởi 2, và do đó trên. Bước xoay là góc xoay 90 ° quanh tâm.

Bài tập:

Nhiệm vụ của bạn, nếu bạn chấp nhận nó, là viết một hàm hoặc chương trình lấy đầu vào là ma trận vuông, áp dụng hiệu ứng lốc xoáy cho nó và sau đó xuất ra ma trận kết quả.

Đầu vào:

Đầu vào phải là một ma trận vuông của thứ tự ntrong đó n >= 1. Không có giả định nào được thực hiện về các yếu tố của ma trận, chúng có thể là bất cứ thứ gì.

Đầu ra:

Một ma trận vuông có cùng thứ tự sẽ là kết quả của việc áp dụng hiệu ứng tronado cho ma trận đầu vào.

Ví dụ:

Một ma trận trật tự n = 1:

[['Hello']]               ===>    [['Hello']]

Một ma trận trật tự n = 2:

[[1 , 2],                 ===>    [[5 , 1],
 [5 , 0]]                          [0 , 2]]

Một ma trận trật tự n = 5:

[[A , B , C , D , E],             [[+ , 6 , 1 , F , A],
 [F , G , H , I , J],              [- , 9 , 8 , 7 , B],
 [1 , 2 , 3 , 4 , 5],     ===>     [/ , 4 , 3 , 2 , C],
 [6 , 7 , 8 , 9 , 0],              [* , I , H , G , D],
 [+ , - , / , * , %]]              [% , 0 , 5 , J , E]]

Tôi nghĩ rằng bạn muốn làm rõ rằng các góc quay là các góc quay 90 °.
Erik the Outgolfer 31/07/18

Ngoài ra, bạn đã thực hiện thử thách này từ một nơi khác? Nếu vậy, bạn phải cung cấp ghi công.
Erik the Outgolfer 31/07/18

1
@EriktheOutgolfer 1) Tôi đã làm rõ điều đó. 2) Thử thách này là của tôi.
ibrahim mahrir

4
@Giuseppe Phụ thuộc vào bán cầu mà bạn đang ở;)
Jo King

12
Đầu tiên tôi muốn nói rằng tôi nghĩ đây là một thử thách tốt: làm tốt lắm! Nhưng tôi cũng muốn đưa ra quan điểm này bởi vì tôi nghĩ rằng sự lựa chọn của bạn để nói rằng đó có thể là bất kỳ loại dữ liệu nào khiến thách thức của bạn ở một điểm khó xử. Tương tự như vậy với tuyên bố của bạn về đầu vào là một danh sách các danh sách, bạn đã hạn chế các ngôn ngữ có thể giải quyết vấn đề này mà không làm việc trên cao. Tôi nghĩ rằng thách thức là tốt hơn nếu những yêu cầu này được thư giãn. Tôi hy vọng bạn tiếp tục đăng những thử thách tốt đẹp như thế này! :)
FryAmTheEggman

Câu trả lời:


5

Python 3 , 100 byte

import numpy
def f(a):
 if len(a): a=numpy.rot90(a,axes=(1,0));a[1:-1,1:-1]=f(a[1:-1,1:-1]);return a

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


8
Python cổ điển, chỉ cần thả xuống a[1:-1,1:-1]=f(a[1:-1,1:-1])như là điều bình thường nhất trên thế giới để trực tiếp lấy và thiết lập toàn bộ bên trong mảng 2 chiều
ETHproductions

1
@ETHproductions Để công bằng, một phần của cú pháp được kế thừa từnumpy
Jo King

1
numpy.rot90(a,1,(1,0))ngắn hơn 3 byte và cũng sẽ hoạt động.
Graodes

1
Điểm của liên kết TIO mà không có bất kỳ trường hợp thử nghiệm nào? ..: S Đây là với (bỏ khoảng trống ở if len(a):a=...-1 byte).
Kevin Cruijssen

5

Than , 44 byte

≔EθSθWθ«≔Eθ⮌⭆觧θνλθθM¹⁻¹Lθ≔E✂θ¹±¹¦¹✂κ¹±¹¦¹θ

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã. Chỉ hoạt động trên các ô vuông ký tự vì I / O mặc định của Char than không thực hiện công bằng mảng bình thường. Giải trình:

≔EθSθ

Đọc hình vuông nhân vật.

Wθ«

Vòng lặp cho đến khi nó trống rỗng.

≔Eθ⮌⭆觧θνλθ

Xoay nó.

θM¹⁻¹Lθ

In nó, nhưng sau đó di chuyển con trỏ đến một hình vuông theo đường chéo từ góc ban đầu.

≔E✂θ¹±¹¦¹✂κ¹±¹¦¹θ

Cắt bên ngoài từ mảng.


5

Thạch , 27 byte

J«þ`UṚ«Ɗ‘ịZU$LСŒĖḢŒHEƊƇṁµG

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

Tôi nghĩ rằng điều này có thể ngắn hơn nhiều.

           Input: n×n matrix A.
J          Get [1..n].
 «þ`       Table of min(x, y).
    UṚ«Ɗ   min with its 180° rotation.

Now we have a matrix like: 1 1 1 1 1
                           1 2 2 2 1
                           1 2 3 2 1
                           1 2 2 2 1
                           1 1 1 1 1

‘ị          Increment all, and use as indices into...
     LС    List of [A, f(A), f(f(A)), …, f^n(A)]
  ZU$       where f = rotate 90°

Now we have a 4D array (a 2D array of 2D arrays).
We wish to extract the [i,j]th element from the [i,j]th array.

ŒĖ     Multidimensional enumerate

This gives us: [[[1,1,1,1],X],
                [[1,1,1,2],Y],
                ...,
                [[n,n,n,n],Z]]

ḢŒHEƊƇ     Keep elements whose Ḣead (the index) split into equal halves (ŒH)
           has the halves Equal to one another. i.e. indices of form [i,j,i,j]
           (Also, the head is POPPED from each pair, so now only [X] [Y] etc remain.)

ṁµG        Shape this like the input and format it in a grid.

1
Bạn có thể chỉ cần đặt µGchân trang và tuyên bố rằng bài nộp của bạn là 25.
Ông Xcoder

5

Perl 6 , 78 73 72 byte

Cảm ơn nwellnhof cho -5 byte!

$!={my@a;{(@a=[RZ] rotor @_: sqrt @_)[1..*-2;1..@a-2].=$!}if @_;@a[*;*]}

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

Khối mã đệ quy lấy một mảng 2D được làm phẳng và trả về một mảng được làm phẳng tương tự.

Giải trình:

$!={      # Assign code block to pre-declared variable $!
    my@a; # Create local array variable a
   {
     (@a=[RZ]  # Transpose:
             rotor @_: sqrt @_;  # The input array converted to a square matrix
     )[1..*-2;1..@a-2].=$!  # And recursively call the function on the inside of the array
   }if @_;    # But only do all this if the input matrix is not empty
   @a[*;*]  # Return the flattened array
}

Bạn có thể sử dụng @a[*;*]thay vì map |*,@alàm phẳng mảng. (Sẽ thật tuyệt nếu có một cách để làm việc với các mảng không được làm phẳng và các chỉ mục đa chiều, nhưng tôi không thể nghĩ ra một.)
nwellnhof

Nhưng @a[1..*-2;1..@a-2].=$!hoạt động.
nwellnhof

5

Octave , 86 81 byte

f(f=@(g)@(M,v=length(M))rot90({@(){M(z,z)=g(g)(M(z=2:v-1,z)),M}{2},M}{1+~v}(),3))

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

Tôi biết rằng các hàm ẩn danh đệ quy không phải là phương pháp ngắn nhất để thực hiện mọi thứ trong Octave, nhưng chúng là phương thức thú vị nhất cho đến nay. Đây là chức năng ẩn danh ngắn nhất tôi có thể nghĩ ra, nhưng tôi rất muốn bị ruồng bỏ.

Giải trình

Hàm đệ quy được xác định theo này trả lời bởi Barecat. là cấu trúc cơ bản của một hàm ẩn danh như vậy, với lệnh gọi đệ quy. Vì điều này sẽ lặp lại vô thời hạn, chúng tôi gói cuộc gọi đệ quy trong một mảng ô có điều kiện : . Hàm ẩn danh với danh sách đối số trống sẽ trì hoãn việc đánh giá sau khi điều kiện đã được chọn (mặc dù sau này, chúng ta thấy rằng chúng ta có thể sử dụng danh sách đối số đó để xác định ). Cho đến nay nó chỉ là kế toán cơ bản.q=f(f=@(g)@(M) ... g(g)(M) ...g(g)(M){@()g(g)(M),M}{condition}()z

Bây giờ cho công việc thực tế. Chúng tôi muốn hàm trả về rot90(P,-1)với P một ma trận g(g)đã được gọi đệ quy ở phần trung tâm của M. Chúng tôi bắt đầu bằng cách đặt z=2:end-1mà chúng tôi có thể ẩn trong việc lập chỉ mục của M. Bằng cách này, M(z,z)chọn phần trung tâm của ma trận cần bị lốc xoáy hơn nữa bởi một cuộc gọi đệ quy. Phần ,3đảm bảo rằng các vòng quay theo chiều kim đồng hồ. Nếu bạn sống ở bán cầu nam, bạn có thể loại bỏ bit này trong -2 byte.

Chúng tôi sau đó làm M(z,z)=g(g)M(z,z) . Tuy nhiên, giá trị kết quả của thao tác này chỉ là phần trung tâm được sửa đổi chứ không phải toàn bộ Pma trận. Do đó, chúng tôi làm điều {M(z,z)=g(g)M(z,z),M}{2}mà về cơ bản là bị đánh cắp từ câu trả lời này của Stewie Griffin.

Cuối cùng, conditionchỉ là đệ quy dừng khi đầu vào trống.


+1 cho bán cầu nam
mèo trần

Tôi chưa thử quấn đầu đệ quy trong các hàm ẩn danh, vì vậy tôi sẽ không thử, nhưng tôi tò mò muốn xem liệu đệ quy có ngắn hơn các vòng trong cái này không .
Stewie Griffin

@StewieGriffin tôi sẽ xem những gì tôi có thể làm :)
Sanchises

@StewieGriffin Nhân tiện, xin vui lòng cảm thấy thách thức khi đăng một phiên bản dựa trên vòng lặp cho thử thách này trong Octave. Tôi thực sự tự hỏi nếu bạn có thể đánh bại cách tiếp cận đệ quy.
Sanchises

4

R , 87 byte

function(m,n=nrow(m)){for(i in seq(l=n%/%2))m[j,j]=t(apply(m[j<-i:(n-i+1),j],2,rev));m}

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



Được phép không? Hình ảnh hiển thị một mũi tên theo chiều kim đồng hồ và mô tả bên dưới nó cho biết xoay theo chiều kim đồng hồ ...
digEmAll

Tôi đã phải đọc câu hỏi mười lần và không bao giờ nhận thấy nó nói theo chiều kim đồng hồ (do đó bình luận của tôi). Than ôi.
Giuseppe

Eheh, nói cho tôi biết về nó ... Tôi là vua của những bài viết sai: D
digEmAll

1
Thật không may, ma trận 1x1 sẽ không hoạt động (vì seq(0.5)trả về 1 thay vì vectơ trống)
digEmAll

4

TOÁN , 25 24 23 22

t"tX@Jyq-ht3$)3X!7Mt&(

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

Lập chỉ mục trong MATL không bao giờ dễ dàng, nhưng với một số môn đánh gôn, nó thực sự đánh bại câu trả lời Jelly tốt nhất hiện tại ...

t                       % Take input implicitly, duplicate.  
 "                      % Loop over the columns of the input*
   X@                   % Push iteration index, starting with 0. Indicates the start of the indexing range.
     Jyq-               % Push 1i-k+1 with k the iteration index. Indicates the end of the indexing range
         t              % Duplicate for 2-dimensional indexing.
  t       3$)           % Index into a copy of the matrix. In each loop, the indexing range gets smaller
             3X!        % Rotate by 270 degrees anti-clockwise
                7Mt&(   % Paste the result back into the original matrix. 

* Đối với một n x nma trận, chương trình này thực hiện các nbước lặp, trong khi bạn thực sự chỉ cần n/2xoay. Tuy nhiên, việc lập chỉ mục trong MATL (AB) đủ linh hoạt để lập chỉ mục các phạm vi không thể chỉ là không có. Theo cách này, không cần lãng phí byte để có được số lần lặp vừa phải.



3

K (ngn / k) , 41 39 38 byte

{s#(+,/'4(+|:)\x)@'4!1+i&|i:&/!s:2##x}

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

{ } chức năng với đối số x

#x độ dài của x - chiều cao của ma trận

2##x hai bản sao - chiều cao và chiều rộng (được coi là giống nhau)

s: giao cho s cho "hình"

!stất cả các chỉ số của một ma trận có hình dạng s, ví dụ !5 5

(0 0 0 0 0 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 4 4 4 4 4
 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4)

Đây là ma trận 2 hàng (danh sách các danh sách) và các cột của nó tương ứng với các chỉ số trong ma trận 5x5.

&/ tối thiểu trên hai hàng:

0 0 0 0 0 0 1 1 1 1 0 1 2 2 2 0 1 2 3 3 0 1 2 3 4

i&|i:gán cho i, đảo ngược ( |) và lấy cực tiểu ( &) vớii

0 0 0 0 0 0 1 1 1 0 0 1 2 1 0 0 1 1 1 0 0 0 0 0 0

Đây là các số vòng phẳng của ma trận 5x5:

4!1+ thêm 1 và lấy phần dư modulo 4

(+|:)là một chức năng xoay bằng cách đảo ngược ( |- chúng ta cần :buộc nó phải đơn điệu) và sau đó hoán vị ( +- vì nó không phải là động từ ngoài cùng bên phải trong "tàu", chúng ta không cần a :)

4(+|:)\x áp dụng nó 4 lần vào x , bảo toàn kết quả trung gian

,/' làm phẳng mỗi

+ hoán vị

( )@' lập chỉ mục cho mỗi giá trị bên trái với mỗi giá trị bên phải

s# định hình lại để s


2
Tôi sẽ rất vui khi thấy lời giải thích về mã của bạn
Galen Ivanov

1
@GalenIvanov Chắc chắn rồi. Tôi không nghĩ rằng tôi có thể chơi golf thêm nữa, vì vậy tôi cũng có thể cố gắng giải thích nó.
ngn

Cảm ơn! Giải pháp của bạn khiến tôi muốn bắt đầu học k (hoặc thậm chí ngn / k :))
Galen Ivanov

@GalenIvanov Làm quen với J (và APL?), Bạn đã đi được nửa đường rồi. K là nhỏ hơn và đơn giản hơn, vì vậy tôi rất muốn khuyên bạn nên học nó, và dĩ nhiên, tôi rất vui để trò chuyện về nó trong Orchard bất cứ lúc nào. ngn / k chỉ là một tập hợp con của thực tế nhưng tôi có mục đích làm cho nó nhanh và thực tế.
ngn

Vâng, tôi nghĩ rằng tôi sẽ thử nó.
Galen Ivanov

3

JavaScript (ES6), 99 byte

f=(a,k=m=~-a.length/2)=>~k?f(a.map((r,y)=>r.map(v=>y-m>k|m-y>k|--x*x>k*k?v:a[m+x][y],x=m+1)),k-1):a

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

Làm sao?

Cho một ma trận vuông có chiều rộng W, Chúng tôi xác định:

m= =W-12tx,y= =tối đa(|y-m|,|x-m|)

Ví dụ đầu ra của tx,y cho ma trận 5x5 (W= =5, m= =2):

(2222221112210122111222222)

Chúng tôi bắt đầu với k= =m và thực hiện xoay 90 ° theo chiều kim đồng hồ của tất cả các ô (x,y) thỏa mãn:

tx,yk

trong khi những cái khác không thay đổi

Điều này tương đương với việc nói rằng một ô không được xoay nếu chúng ta có:

(y-m>k) HOẶC LÀ (m-y>k) HOẶC LÀ (X2>k2) với X= =m-x

đó là thử nghiệm được sử dụng trong mã:

a.map((r, y) =>
  r.map(v =>
    y - m > k | m - y > k | --x * x > k * k ?
      v
    :
      a[m + x][y],
    x = m + 1
  )
)

Sau đó, chúng tôi giảm k và bắt đầu lại, cho đến khi k= =-1 hoặc là k= =-3/2 (tùy thuộc vào tính chẵn lẻ của W). Dù bằng cách nào, nó kích hoạt điều kiện tạm dừng của chúng tôi:

~k === 0

3

Thạch , 24 byte

ṙ⁹ṙ€
ḊṖ$⁺€ßḷ""ç1$ç-ZUµḊ¡

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

Tôi nghĩ rằng điều này có thể ngắn hơn nhiều.

- Lynn


Tôi tự hỏi về một giải pháp như thế này! Điều đó có ḷ""vẻ kỳ diệu với tôi ^^ quan tâm để thêm một lời giải thích?
Lynn

@Lynn Điều cuối cùng tôi mong đợi là nghe điều đó ḷ""thật kỳ diệu. Chỉ là ḷ"có thêm "... ồ, có một khả năng nhỏ đó ḷ"cũng là thứ mà tôi đã "phát minh" chưa được sử dụng nhiều vì đôi khi nó có thể được thay thế bằng một nguyên tử duy nhất (không phải trong trường hợp này, như trong trường hợp này, như đầu vào có thể chứa 0quá).
Erik the Outgolfer

2

Haskell , 108 byte

e=[]:e
r=foldl(flip$zipWith(:))e
g!(h:t)=h:g(init t)++[last t]
f[x,y]=r[x,y]
f[x]=[x]
f x=r$(r.r.r.(f!).r)!x

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

Tôi đã sử dụng chuyển vị của Laikoni và sửa đổi nó một chút, để xoay một mảng 90 °:

  e=[]:e;foldr(zipWith(:))e.reverse
 e=[]:e;foldl(flip$zipWith(:))e

Giải trình

r xoay một mảng bằng 90 °.

(!)là một chức năng cấp cao hơn: áp dụng cho trung tâm. g![1,2,3,4,5][1] ++ g[2,3,4] ++ [5].

f là hàm lốc xoáy: các trường hợp cơ sở có kích thước 1 và 2 (bằng cách nào đó 0 không hoạt động).

Dòng cuối cùng là nơi phép màu xảy ra: chúng tôi áp dụng r.r.r.(f!).rtrên các hàng giữa xvà sau đó xoay kết quả. Hãy gọi những hàng giữa M . Chúng tôi muốn lặp lại trên các cột giữa của M và để có được những cột đó, chúng tôi có thể xoay M và sau đó sử dụng (f!). Sau đó, chúng tôi sử dụng r.r.rđể xoay M trở lại hướng ban đầu của nó.


2

Java 10, 198 192 byte

m->{int d=m.length,b=0,i,j;var r=new Object[d][d];for(;b<=d/2;b++){for(i=b;i<d-b;i++)for(j=b;j<d-b;)r[j][d+~i]=m[i][j++];for(m=new Object[d][d],i=d*d;i-->0;)m[i/d][i%d]=r[i/d][i%d];}return r;}

-6 byte nhờ @ceilingcat .

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

Giải trình:

m->{                         // Method with Object-matrix as both parameter and return-type
  int d=m.length,            //  Dimensions of the matrix
      b=0,                   //  Boundaries-integer, starting at 0
      i,j;                   //  Index-integers
  var r=new Object[d][d];    //  Result-matrix of size `d` by `d`
  for(;b<=d/2;b++){          //  Loop `b` in the range [0, `d/2`]
    for(i=b;i<d-b;i++)       //   Inner loop `i` in the range [`b`, `d-b`)
      for(j=b;j<d-b;)        //    Inner loop `j` in the range [`b`, `d-b`)
        r[j][d+~i]=          //     Set the result-cell at {`j`, `d-i-1`} to:
          m[i][j++];         //      The cell at {`i`, `j`} of the input-matrix
    for(m=new Object[d][d],  //   Empty the input-matrix
        i=d*d;i-->0;)        //   Inner loop `i` in the range (`d*d`, 0]
      m[i/d][i%d]            //     Copy the cell at {`i/d`, `i%d`} from the result-matrix
        =r[i/d][i%d];}       //      to the replaced input-matrix
  return r;}                 //  Return the result-matrix as result

bvề cơ bản được sử dụng để chỉ ra chiếc nhẫn nào chúng ta đang ở. Và sau đó nó sẽ xoay vòng này, bao gồm mọi thứ bên trong nó một lần theo chiều kim đồng hồ trong mỗi lần lặp.

Việc thay thế ma trận đầu vào được thực hiện do Java là tham chiếu qua, do đó, cài đặt đơn giản r=mcó nghĩa là cả hai ma trận đều được sửa đổi khi sao chép từ các ô, gây ra kết quả không chính xác. Do đó, chúng ta phải tạo một Object-matrix mới (tham chiếu mới) và sao chép từng giá trị trong từng ô một thay thế.


1

MATLAB, 93 byte

function m=t(m),for i=0:nnz(m),m(1+i:end-i,1+i:end-i)=(rot90(m(1+i:end-i,1+i:end-i),3));end;end

Tôi chắc chắn rằng điều này có thể được đánh gôn thêm bằng cách nào đó.

Giải trình

function m=t(m),                                                                          end % Function definition
                for i=0:nnz(m),                                                       end;    % Loop from 0 to n^2 (too large a number but matlab indexing doesn't care)
                                                            m(1+i:end-i,1+i:end-i)            % Take the whole matrix to start, and then smaller matrices on each iteration
                                                      rot90(                      ,3)         % Rotate 90deg clockwise (anti-clockwise 3 times)
                               m(1+i:end-i,1+i:end-i)=                                        % Replace the old section of the matrix with the rotated one


1

Haskell, 274 byte

wlà chức năng chính, có loại [[a]] -> [[a]]mà bạn mong đợi.

Tôi chắc chắn một tay golf Haskell giàu kinh nghiệm hơn có thể cải thiện điều này.

w m|t m==1=m|0<1=let m'=p m in(\a b->[h a]++x(\(o,i)->[h o]++i++[f o])(zip(tail a)b)++[f a])m'(w(g m'))
p m|t m==1=m|0<1=z(:)(f m)(z(\l->(l++).(:[]))(r(x h(i m)):(p(g m))++[r(x f(i m))])(h m))
t[]=1
t[[_]]=1
t _=0
h=head
f=last
x=map
i=tail.init
g=x i.i
z=zipWith
r=reverse

Bạn có thể muốn xem các mẹo của chúng tôi để chơi gôn trong Haskell, ví dụ: Sử dụng vệ sĩ thay vì điều kiện sẽ tiết kiệm một số byte.
Laikoni
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.