Обертання 2D матриці


30

Скажімо, у мене є така (2D) матриця:

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

Обертайте матрицю проти годинникової стрілки R (не з кроком 90 градусів, кожен раз на 1 число),

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

Виконаний приклад:

Вхід:

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

Вихід:

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

(дивні пробіли - це вирівнювання чисел у приємних стовпцях)

Зовнішнє "кільце" матриці обертається 2 проти годинникової стрілки, а внутрішнє праве обертається 2 також. У цій матриці є лише два кільця.

Приклад з 1 "кільцем":

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

Потрібно вивести:

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

Ваше завдання полягає в тому, щоб взяти матрицю і ціле число Rі вивести перекладену версію після Rобертання.

Обертання матриці 4x5 представлене наступним малюнком: введіть тут опис зображення

Обмеження:

  • 2 ≤ M, N ≤ 100, де M і N - розміри матриці. Гарантується, що мінімум M і N будуть парними.
  • 1 ≤ R ≤ 80, де r - кількість обертів.
  • Матриця завжди буде містити лише додатні цілі числа.
  • Цінності не завжди відрізняються.
  • Вхід завжди повинен бути як двовимірний масив (якщо ви не можете прийняти вхід виконання як 2D масив, тоді вам просто потрібно знайти інший спосіб отримати введення).

Ще один тестовий випадок із невідмінними значеннями:

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

Виходи:

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

Це , тому найкоротша відповідь виграє!





4
@ceasedtoturncounter clockwis Ваше ім'я дуже іронічне для цього виклику ...
HyperNeutrino

1
[[3, 4, 8, 12], [2, 11, 10, 16], [1, 7, 6, 16], [5, 9, 13, 14]]16 раптово дублюється я припускаю , що це повинно бути: [[3, 4, 8, 12], [2, 11, 10, 16], [1, 7, 6, 15], [5, 9, 13, 14]]?
Крістоф

Відповіді:



5

Октава, 210 байт

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

Спробуйте його на Octave Online!

Безгольова версія:

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)

Пояснення:

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

Функція, яка отримує число і генерує діапазон, який впорядковується та центрирується для введення 4 (парного), генерує -2 -1 1 2
для введення 5 (непарне), генерує -2.5 -1.5 0 1 2
лише його, слід упорядкувати та по центру

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

складна матриця, породжена діапазонами

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

Перетворіть прямокутні в полярні координати та кути повернення, так що для кожного кута кільця відсортовано проти годинникової стрілки

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

Створена наступна матриця

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

d=bwdist(B,'chessboard');

Обчислює дистанційне перетворення B, використовуючи відстань шахової дошки для генерації кільцевих індексів

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

для матриці 6 * 7 у нас буде така матриця

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(:)]);

лексикографічне сортування спочатку на основі індексу кільця, а потім за порядком кута (повертаються індекси відсортованих елементів)

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

і нарешті круговий зсув кожного кільця.


4

Python 3, 292 288 байт

_=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])

Здійснює введення з вилученими новими рядками, але залишає пробіл після кількості приростів, щоб обертати його.

Пояснення:

Замість моделювання матриці у вигляді серії концентричних кілець за пропозицією ОП можна замість цього розділити її на чотири області, де елементи рухаються або вгору, вниз, вправо або вліво під час одного обертання. Це мета довгих рядків eval-ed f: визначити, до якої області i,jналежить кожна комбінація. Потім результат цього переглядають двічі l, надаючи елементу, який повинен повернутись у положення i,jна наступному кроці. Функція, gяка виконує все це і утворює нову матрицю після одного кроку, потім повторюється викликом, повторюючи згенеровану рядок, що містить подання вкладеного виклику функції.

Коли я це зробив спочатку, я випадково спричинив обертання матриці за годинниковою стрілкою, а не проти. Замість того, щоб правильно виправити, я додав дві стратегічно розміщені копії, [::-1]щоб повернути матрицю до та після обертання. Можливо, це можна було б відібрати в гольф до ~ 280 276 байт, але я занадто ледачий для цього.

Крім того, це швидкий неперевірений порт з трохи більш тривалої програми Python 2, тому вибачте мене, якщо він працює не зовсім правильно. Ось код Python 2 у будь-якому разі:

_=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: Golfed від 4 байта, замінивши orв |два рази. andНа жаль, не можна допомогти.


Ласкаво просимо до PPCG! Гарний перший пост!
HyperNeutrino

Смішна історія насправді - в моєму середньому школі, який пройшов марш, ми дізналися формацію, де всі рухаються в концентричних прямокутних «кільцях», подібних до цього питання, і я одразу подумав цю відповідь.
Айдан Ф. Пірс

1

Perl, 330 328 байт

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}

Спробуйте це на Ideone .

Безголовки:

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;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.