Xoay ma trận 2D


30

Giả sử tôi có ma trận (2D) sau:

[[1,  2,  3,  4 ],
 [5,  6,  7,  8 ],
 [9,  10, 11, 12],
 [13, 14, 15, 16]]

Xoay ma trận lần ngược chiều kim đồng hồ R (không tăng theo 90 độ, chỉ 1 số mỗi lần),

1  2  3  4             2 3   4  8         3   4   8  12
5  6  7  8    -->      1 7  11 12   -->   2  11  10  16 
9  10 11 12            5 6  10 16         1   7   6  15 
13 14 15 16            9 13 14 15         5   9  13  14

Ví dụ đã hoàn thành:

Đầu vào:

2
[[1,  2,  3,  4 ],
 [5,  6,  7,  8 ],
 [9,  10, 11, 12],
 [13, 14, 15, 16]]

Đầu ra:

[[3,  4,  8, 12],
 [2, 11, 10, 16],
 [1,  7,  6, 15],
 [5,  9, 13, 14]]

(không gian lạ là sắp xếp các số trong các cột đẹp)

"Vòng" bên ngoài của ma trận quay 2 chiều ngược chiều kim đồng hồ và bên phải cũng xoay 2 vòng. Trong ma trận này, chỉ có hai vòng.

Một ví dụ với 1 "vòng":

2
[[1, 2],
 [3, 4],
 [5, 6]]

Nên đầu ra:

[[4, 6],
 [2, 5],
 [1, 3]]

Thách thức của bạn là đưa vào một ma trận và một số nguyên R, và xuất phiên bản dịch sau khi Rxoay.

Xoay của ma trận 4x5 được biểu thị bằng hình sau: nhập mô tả hình ảnh ở đây

Các ràng buộc:

  • 2 ≤ M, N ≤ 100, trong đó M và N là kích thước của ma trận. Nó được đảm bảo rằng tối thiểu của M và N sẽ là số chẵn.
  • 1 ≤ R ≤ 80, trong đó r là số vòng quay.
  • Ma trận sẽ chỉ bao gồm các số nguyên dương.
  • Giá trị không phải lúc nào cũng khác biệt.
  • Đầu vào phải luôn là một mảng 2D (nếu bạn không thể lấy đầu vào thời gian chạy dưới dạng mảng 2D, thì bạn chỉ cần tìm một cách khác để nhận đầu vào).

Một trường hợp thử nghiệm khác, với các giá trị không khác biệt:

1
[[1, 1],
 [2, 2],
 [3, 3]]

Đầu ra:

[[1, 2],
 [1, 3],
 [2, 3]]

Đây là , vì vậy câu trả lời ngắn nhất sẽ thắng!





4
@ceasetoturncountclockwis Tên của bạn rất mỉa mai cho thử thách này ...
HyperNeutrino

1
[[3, 4, 8, 12], [2, 11, 10, 16], [1, 7, 6, 16], [5, 9, 13, 14]]16 đột nhiên bị trùng lặp Tôi đoán nó phải là : [[3, 4, 8, 12], [2, 11, 10, 16], [1, 7, 6, 15], [5, 9, 13, 14]]?
Christoph

Câu trả lời:



5

Octave, 210 byte

function M=F(M,R);f=@(z)[-z/2:-1 !eye(!!mod(z,2)) 1:z/2];t=angle(f([x y]=size(M))'+f(y)*i);B=!!M;B(2:x-1,2:y-1)=0;d=bwdist(B,'ch');[~,I]=sortrows([d(:) t(:)]);for k=0:max(d(:));M(h)=shift(M(h=I(d(I)==k)),R);end

Hãy thử nó trên Octave Online!

Phiên bản bị đánh cắp:

function M=F(M,R)
    [x y]=size(M);
    f=@(z)[-z/2:-1 !eye(!!mod(z,2)) 1:z/2];
    t=angle(f(x)'+f(y)*i);
    B=!!M;
    B(2:x-1,2:y-1)=0;
    d=bwdist(B,'chessboard');
    [~,I]=sortrows([d(:) t(:)]);
    for k=0:max(d(:))
        M(h)=shift(M(h=I(d(I)==k)),R);
    end
end
R=2;
M=randi(10,4,7)
F(M,R)

Giải trình:

f=@(z)[-z/2:-1 !eye(!!mod(z,2)) 1:z/2]; 

Hàm lấy số và tạo phạm vi được sắp xếp và căn giữa cho đầu vào 4 (chẵn) tạo -2 -1 1 2
cho đầu vào 5 (lẻ) -2.5 -1.5 0 1 2
chỉ tạo ra nó nên được đặt hàng và căn giữa

f(x)'+f(y)*i    

một ma trận phức tạp được tạo ra từ các phạm vi

(-2,-2.5) (-2,-1.5) (-2,0) (-2,1) (-2,2)
(-1,-2.5) (-1,-1.5) (-1,0) (-1,1) (-1,2)
(1,-2.5)  (1,-1.5)  (1,0)  (1,1)  (1,2)
(2,-2.5)  (2,-1.5)  (2,0)  (2,1)  (2,2)

t=angle(f(x)'+f(y)*i);                    

Chuyển đổi tọa độ hình chữ nhật sang cực và góc quay lại để cho mỗi góc vòng được sắp xếp theo chiều kim đồng hồ

-2.25  -2.50  3.14  2.68  2.36
-1.95  -2.16  3.14  2.36  2.03
-1.19  -0.98  0.00  0.79  1.11
-0.90  -0.64  0.00  0.46  0.79


B=!!M;
B(2:x-1,2:y-1)=0;

Ma trận sau được tạo

1   1   1   1   1
1   0   0   0   1
1   0   0   0   1
1   1   1   1   1

d=bwdist(B,'chessboard');

Tính toán biến đổi khoảng cách của B bằng khoảng cách bàn cờ để tạo các chỉ số vòng

0   0   0   0   0
0   1   1   1   0
0   1   1   1   0
0   0   0   0   0               

đối với ma trận 6 * 7 chúng ta sẽ có ma trận sau

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

[~,I]=sortrows([d(:) t(:)]);

sắp xếp từ vựng trước tiên dựa trên chỉ số vòng và sau đó theo thứ tự góc (chỉ số của các phần tử được sắp xếp trả về)

    for k=0:max(d(:))
        M(h)=shift(M(h=I(d(I)==k)),R);
    end

và cuối cùng là dịch chuyển vòng tròn mỗi vòng.


4

Python 3, 292 288 byte

_=eval
a=input().split()
b,a=int(a[0]),_("".join(a[1:]))[::-1]
c=len(a)
d=len(a[0])
e=range
f="int((i>=j and i+j<c-1)|2*(i>=c/2and i+d>j+c)|3*(i<c/2and i+j<d))"
l=[-1,1,0,0],[0,0,1,-1]
g=lambda x:[[x[i+l[0][_(f)]][j+l[1][_(f)]]for j in e(d)]for i in e(c)]
print(_("g("*b+"a"+")"*b)[::-1])

Mất đầu vào với dòng mới, nhưng để lại một khoảng trắng sau số lần tăng để xoay nó theo.

Giải trình:

Thay vì mô hình hóa ma trận dưới dạng một loạt các vòng tròn đồng tâm theo đề xuất của OP, thay vào đó, người ta có thể chia nó thành bốn vùng nơi các phần tử di chuyển lên, xuống, phải hoặc trái trong một vòng quay. Đây là mục đích của chuỗi eval-ed dài f: để xác định khu vực mà mỗi i,jkết hợp rơi vào. Sau đó, kết quả của điều đó được tra cứu hai lần l, đưa ra phần tử phải xoay vào vị trí i,jtrong bước tiếp theo. Hàm gthực hiện tất cả điều này và tạo thành ma trận mới sau một bước duy nhất sau đó được gọi lặp lại bằng cách xóa một chuỗi được tạo có chứa biểu diễn của một lệnh gọi hàm lồng nhau.

Khi tôi thực hiện điều này ban đầu, tôi đã vô tình khiến ma trận quay theo chiều kim đồng hồ thay vì ngược chiều kim đồng hồ. Thay vì thực hiện một sửa chữa thích hợp, tôi đã thêm hai bản sao được đặt một cách chiến lược [::-1]để đảo ngược ma trận trước và sau khi xoay. Chúng có thể được đánh golf tới ~ 280 276 byte, nhưng tôi quá lười để làm điều đó.

Ngoài ra, đây là một cổng chưa được kiểm tra nhanh từ chương trình Python 2 dài hơn một chút, vì vậy hãy tha thứ cho tôi nếu nó không hoạt động hoàn toàn đúng. Đây là mã Python 2, dù sao đi nữa:

_=eval
a=raw_input().split()
b,a=int(a[0]),_("".join(a[1:]))[::-1]
c=len(a)
d=len(a[0])
e=xrange
f="int((i>=j and i+j<c-1)|2*(i>=c/2and i+d>j+c)|3*(i<c/2and i+j<d))"
l=[-1,1,0,0],[0,0,1,-1]
g=lambda x:[[x[i+l[0][_(f)]][j+l[1][_(f)]]for j in e(d)]for i in e(c)]
print _("g("*b+"a"+")"*b)[::-1]

EDIT: Giảm 4 byte bằng cách thay thế orbằng |hai lần. andThật không thể giúp được, thật không may.


Chào mừng đến với PPCG! Bài đăng đầu tiên rất hay!
HyperNeutrino

Câu chuyện vui thực sự - trong ban nhạc diễu hành ở trường trung học của tôi hôm nay chúng tôi đã học được một đội hình trong đó mọi người di chuyển trong các "vòng tròn" hình chữ nhật đồng tâm tương tự như câu hỏi này, và tôi nghĩ ngay đến câu trả lời này.
Aidan F. Pierce

1

Perl, 330 328 byte

sub f{($r,$m)=@_;$h=@m=@$m;for$s(0..(($w=$#{$m[0]})<--$h?$w:$h)/2-.5){@_=(@{$m[$s]}[@x=$s..($x=$w-$s)],(map$m[$_][$x],@y=1+$s..($y=$h-$s)-1),reverse(@{$m[$y]}[@x]),(map$m[$h-$_][$s],@y));push@_,shift
for 1..$r;@{$m[$s]}[@x]=map shift,@x;$m[$_][$x]=shift for@y;@{$m[$y]}[@x]=reverse map shift,@x;$m[$h-$_][$s]=shift for@y}@$m=@m}

Hãy thử nó trên Ideone .

Ung dung:

sub f {
    my ($r, $m) = @_;

    my @m = @$m;
    my $h = $#m;
    my $w = @{$m[0]} - 1;
    my $c = (($w < $h ? $w : $h) + 1) / 2 - 1;

    for my $s (0 .. $c) {
        my $x = $w - $s;
        my $y = $h - $s;
        my @x = $s .. $x;
        my @y = $s + 1 .. $y - 1;

        # One circle.
        @_ = (@{$m[$s]}[@x],
              (map { $m[$_][$x] } @y),
              reverse(@{$m[$y]}[@x]),
              (map { $m[$h - $_][$s] } @y));

        # Circular shift.
        push(@_, shift(@_)) for 1 .. $r;

        @{$m[$s]}[@x] = map { shift(@_) } @x;
        $m[$_][$x] = shift(@_) for @y;
        @{$m[$y]}[@x] = reverse(map { shift(@_) } @x);
        $m[$h - $_][$s] = shift(@_) for @y;
    }

    @$m = @m;
}
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.