Підсумок обертання


26

Візьміть як вхід квадратну матрицю, що містить додатні цілі числа, і обчисліть "повернуту суму" матриці.

Обернена сума:

Візьміть суму вихідної матриці і тієї ж матриці, оберненої на 90, 180 і 270 градусів.

Припустимо, матриця така:

 2    5    8
 3   12    8
 6    6   10

тоді обернена сума складе:

2    5    8     8    8   10    10    6    6     6    3    2
3   12    8  +  5   12    6  +  8   12    3  +  6   12    5  = 
6    6   10     2    3    6     8    5    2    10    8    8   

26   22   26
22   48   22
26   22   26

Тестові приклади:

Введення та вихід, розділені тире, різні тестові випадки, розділені новим рядком. Тестові приклади в більш зручних форматах можна знайти тут .

1
-------------
4

1 3
2 4
-------------
10   10 
10   10    

14    6    7   14
 6   12   13   13
 6    2    3   10
 5    1   12   12
-------------
45   37   24   45
24   30   30   37
37   30   30   24
45   24   37   45    

14    2    5   10    2
18    9   12    1    9
 3    1    5   11   14
13   20    7   19   12
 2    1    9    5    6
-------------
24   29   31   41   24
41   49   31   49   29
31   31   20   31   31
29   49   31   49   41
24   41   31   29   24

Виграє найкоротший код у байтах на кожній мові. Пояснення настійно заохочуються!

Відповіді:


9

Python 2 , 78 байт

Завдяки Деннісу за те, що я розіграв два байти від попереднього рекурсивного підходу

f=lambda*l:l[3:]and[map(sum,zip(*d))for d in zip(*l)]or f(zip(*l[0][::-1]),*l)

Спробуйте в Інтернеті! або Дивіться тестовий набір.


Python 2 , 80 81 83 85 байт (нерекурсивний)

Вводить введення як однотонний список .

l=input()
exec"l+=zip(*l[-1][::-1]),;"*3
print[map(sum,zip(*d))for d in zip(*l)]

Спробуйте в Інтернеті!

Функціональність коду

Оскільки це досить тривалий аналіз, щоб проаналізувати його в цілому, давайте перевіримо це детально:

f = lambda *l:                # This defines a lambda-function that can accept any number
                              # of arguments (the matrix) using starred expressions.
l[3:] and ...X... or ...Y...  # If l[3:] is truthy (that is, the length of the list is
                              # higher than 3), return X, otherwise Y.

[map(sum,zip(*d))for d in zip(*l)]     # The first expression, X.
[                                ]     # Start a list comprehension, that:
                 for d in              # ... Iterates using a variable d on:
                          zip(*l)      # ... The "input", l, transposed.
         zip(*d)                       # ... And for each d, transpose it...
 map(sum,       )                      # ... And compute the sum of its rows.
                                       # The last two steps sum the columns of d.

f(zip(*l[0][::-1]),*l)     # The second expression, Y. This is where the magic happens.
f(                   )     # Call the function, f with the following arguments:
  zip(*          )         # ... The transpose of:
       l[0][::-1]          # ...... The first element of l (the first arg.), reversed.
                  ,        # And:
                   *l      # ... l splatted. Basically turns each element of l
                           # into a separate argument to the function.

А для другої програми:

l=input()                                # Take input and assign it to a variable l.
                                         # Note that input is taken as a singleton list.

exec"l+=zip(*l[-1][::-1]),;"*3           # Part 1. Create the list of rotations.
exec"                     ;"*3           # Execute (Do) the following 3 times:
     l+=                 ,               # ... Append to l the singleton tuple:
        zip(*           )                # ...... The transpose of:
             l[-1][::-1]                 # ......... The last element of l, reversed.

print[map(sum,zip(*d))for d in zip(*l)]  # Part 2. Generate the matrix of sums.
print                                    # Output the result of this expression:
     [                for d in        ]  # Create a list comprehension, that iterates
                                         # with a variable called "d" over:
                               zip(*l)   # ... The transpose of l.
      map(sum,       )                   # ... And computes the sum:
              zip(*d)                    # ... Of each row in d's transpose.
                                         # The last 2 steps generate the column sums.

TL; DR: Створіть список матриць, необхідних, обертаючи вхід 3 рази на 90 градусів і збираючи результати. Потім отримайте суми стовпців кожної матриці при транспонуванні результату.


f=lambda*l:l[3:]and[map(sum,zip(*d))for d in zip(*l)]or f(zip(*l[0][::-1]),*l)зберігає два байти з "нормальним" входом. Спробуйте в Інтернеті!
Денніс

@Dennis Дякую! Я думав, що lambda*lце не можливо в Python 2 чомусь.
Містер Xcoder

Ви не можете робити x,*y=1,2,3в Python 2.7 або [*x]Python 3.4, але зірочні вирази можна використовувати для аргументів функції навіть у Python 1.6. Спробуйте в Інтернеті!
Денніс


5

Чисто , 110 байт

import StdEnv,StdLib
r=reverse
t=transpose
z=zipWith(+)
$m=[z(z(r b)a)(z(r c)d)\\a<-m&b<-r m&c<-t m&d<-r(t m)]

Спробуйте в Інтернеті!

З матриць:

  • X = transpose(reverse M): Обертання на 90 градусів
  • Y = reverse(map reverse M): Обертання на 180 градусів
  • Z = reverse(transpose M): Обертання на 270 градусів

Це замикає оператор додавання на Mі X, а також, Yі Z, а потім на результати.



5

Джулія 0,6 , 29 байт

x*y=rotr90(y,x)
!x=x+1x+2x+3x

Спробуйте в Інтернеті!

Я не міг потрапити нижче рішення LukeS

Але в спробах я все-таки придумав це, що я думаю, що це якось мило.

Спочатку ми переосмислюємо множення, щоб це було операцією повороту, де вперше - це кількість разів обертати. Отож, оскільки Джулія мультипектируется шляхом співставлення, то: 1xстає rotr90(x,1)і 3xстає rotr90(x,3)тощо

Потім виписуємо суму.


5

Джулія 0,6 , 28 24 байти

~A=sum(rotr90.([A],0:3))

Спробуйте в Інтернеті!

~A=sum(rotr90.([A],0:3)) #
~                        # redefine unary operator ~
 A                       # function argument
               [A]       # put input matrix A into a list with one element
                   0:3   # integer range from 0 to 3
       rotr90.(   ,   )  # apply function rotr90 elementwise, expand singleton dimensions
       rotr90.([A],0:3)  # yields list of rotated matrices:
                         # [rotr90(A,0), rotr90(A,1), rotr90(A,2), rotr90(A,3)]
  sum(                )  # sum

1
Варто, мабуть, зауважити, що робити [1]приклад на слід, ~reshape([1], (1,1))бо саме так матриця 1x1 оголошується в julia 0.6.
Ліндон Уайт


4

MATL , 9 байт

i3:"G@X!+

Спробуйте в MATL Online

Пояснення

i       # Explicitly grab the input matrix
3:"     # Loop through the values [1, 2, 3], and for each value, N:
  G     # Grab the input again
  @X!   # Rotate the value by 90 degrees N times
  +     # Add it to the previous value on the stack
        # Implicitly end the for loop and display the resulting matrix

4

Октава , 33 байти

@(a)a+(r=@rot90)(a)+r(a,2)+r(a,3)

Спробуйте в Інтернеті!

Пояснення:

(r=@rot90)у вбудованому способі створення функціональної ручки, яка rвикористовується для обертання матриці на 90 градусів. Якщо другий аргумент, kдається rтоді він буде повертати матрицю k*90градусів. Отже, це еквівалентно псевдокоду:

a + rot90(a) + rot180(a) + rot270(a)



3

MATL , 7 байт

,t@QX!+

Спробуйте в MATL Online!

Пояснення

Порт моєї відповіді Октави.

,        % Do twice
  t      %   Duplicate. Takes input (implicit) the first time
  @Q     %   Push 1 in the first iteration, and 2 in the second
  X!     %   Rotate by that many 90-degree steps
  +      %   Add
         % End (implicit). Display (implicit)

3

R , 69 64 байт

function(x,a=function(y)apply(y,1,rev))x+a(x)+a(a(x))+a(a(a(x)))

Спробуйте в Інтернеті!


Спроба номер три на кодегольфі. Від 69 до 64 байт завдяки Джузеппе!


Перехід aдо аргументу функції дозволить зберегти байти, дозволяючи позбутися {}навколо тіла функції. Крім того, перенесення підходу Октава Луїса Мендо може врятувати деякі байти? Нарешті, я не на 100% впевнений, але t(apply(x,2,rev))еквівалентний apply(x,1,rev)?
Джузеппе

Дякую, мені вдалося вдосконалитись із порадами №1 та №3. Я не вдалося врятувати байт, додавши аргумент nдля a()повторити операцію , хоча.
Флоріан

1
Я мав на увазі щось подібне
Джузеппе



2

JavaScript (ES6), 77 байт

a=>a.map((b,i)=>b.map((c,j)=>c+a[j][c=l+~i]+a[c][c=l+~j]+a[c][i]),l=a.length)

2

Желе , 7 байт

ṚZ$3СS

Спробуйте в Інтернеті!

Збережено 1 байт завдяки Еріку Атгольферу (також завдяки пропозиції щодо виправлення помилки).

Як?

ṚZ $ 3СS || Повна програма (монадійна).

   3С || Зробіть це 3 рази і збирайте результати у списку
  $ || -> Застосувати останні два посилання як монаду
Ṛ || –––> Зворотний,
 Z || –––> Перенести.
      S || Підсумовування.


2

APL (Dyalog Classic) , 17 байт

{⍵+⌽∘⍉⍵+⌽∘⊖⍵+⍉⌽⍵}

Спробуйте в Інтернеті!

APL NARS 34байт 21 17 символів

{⍵+⌽∘⍉⍵+⌽∘⊖⍵+⍉⌽⍵}

-2 знаки завдяки ngn

-2 знака, оскільки складений оператор ∘, здається, має перевагу над +

здається, що roa повернути на 90 °, roa повернути на 180 °, ⌽⍉⌽⊖a повернути на 270 °, як ⍉⌽

Якщо існує оператор p як:

r←(g p)n;a;i;k
   a←⌽,nr←⍬⋄i0k←⍴a⋄→C
A: B×⍳r≡⍬⋄rg¨r
B: rr,⊂ia
C: A×⍳ki+←1
   r←⌽r

Оператор p вище був би таким, що якщо g - функція 1 аргументу (монадична?), Вона повинна бути:

"g f a a a a" is "a ga gga ggga"

розчином буде ферапс 15 символів

  g←{⊃+/⌽∘⍉ p 4⍴⊂⍵}
  a2 21 3 2 4
  g a
10 10 
10 10 
  g 1
4

Але може бути краще одного оператора, "складеного n часу" d таким, що "3 df w" є f (f (f (w))).

Тепер я щось написав, але це занадто крихко, не потребуючи перевірки типу.

Але мені більше подобається оператор q, який повторює складання f з аргументом m (він не повний, оскільки випадки помилок типів не записуються)

r←(n q f)m;i;k;l
   r←⍬⋄k←⍴,n⋄→A×⍳k1i0⋄→D
C: rr,⊂(in)q f m
D: C×⍳ki+←1
   0
A: lnrm⋄→0×⍳n0
B: l-←1rf r⋄→B×⍳l1

рішення буде 17 символів, але я вважаю за краще це

  g←{⊃+/(0..3)q(⌽⍉)⍵}
  fmt g a
2─────┐
2 10 10
 10 10
└~─────┘
  fmt g 1
4
~

270 може бути справедливим, ⍉⌽і вся справа підходить для поїзда
п.

Якщо є такий f, що gfwwww is w gw ggw gggw, відповідь буде + / ⌽⍉f 4 / rho w
RosLuP

Ви маєте на увазі +/⌽∘⍉f 4⍴⊂⍵? Щоб отримати чотири екземпляри , спочатку слід додати їх . Для того, щоб мати в ⌽⍉якості операнда f, ви повинні скласти його в одну функцію , як це: ⌽∘⍉. Таємничим fможе бути сканування (зворотний косий рядок), але є ще одна деталь, про яку слід подбати - ⌽∘⍉вийде лівий аргумент, тому ми мусимо змусити його ігнорувати: +/{⌽⍉⍵}\4⍴⊂⍵або +/⊢∘⌽∘⍉\4⍴⊂⍵.
ngn

У своєму першому коментарі я пропонував цей поїзд: ⊢ + ⌽∘⍉ + ⌽∘⊖ + ⍉∘⌽. Це може призвести до ще коротших рішень, якщо ви вміло переставляєте візки і добре використовуєте поїзди.
ngn

@ngn навіть проста {⍵ + ⍺} \ 1 2 3 4 Помилка повернення домену
RosLuP

2

K4 / K (oK) , 23 8 байт

Рішення:

+/(|+:)\

Спробуйте в Інтернеті!

Приклад:

+/(|+:)\5 5#14 2 5 10 2 18 9 12 1 9 3 1 5 11 14 13 20 7 19 12 2 1 9 5 6
24 29 31 41 24
41 49 31 49 29
31 31 20 31 31
29 49 31 49 41
24 41 31 29 24

Пояснення:

Завдяки ngn за техніку спрощеного перетворення.

+/(|+:)\ / the solution
       \ / converge
  (   )  / function to converge
    +:   / flip
   |     / reverse
+/       / sum over the result

Додатково:

У Q це можна записати як

sum (reverse flip @) scan


Я знав, що є кращий спосіб застосувати перетворення!
Стрітер

+ / (| + :) \ tio.run/##y9bNz/7/X1tfo0bbSjPGWMFY2UjBVMFCwVjB0AhImQGhocH//wA , на жаль, таке ж число ... Gah не може з'ясувати розмітку на мобільному пристрої.
стрітер

Здається, розмітка в коментарях має помилку, причому не лише на мобільних пристроях - зворотна косою рисою, перш ніж зворотне котирування змінює речі. Я уникнув цього, вставивши пробіл.
ngn

2

Рубі , 74 72 66 байт

->a{r=0...a.size;r.map{|i|r.map{|j|(0..3).sum{i,j=j,~i;a[i][j]}}}}

Спробуйте в Інтернеті!

Це працює на основі елементів за елементами, знаходячи пов'язані елементи математично, а не обертати масив. Ключова частина - це те i,j=j,~i, що повертається (i, j) за годинниковою стрілкою на 90 градусів.

-2 байти завдяки панові Xcoder

-6 байт через sum



1

Рубін 89 79 байт

-10 байт завдяки Unihedron

->m{n=m;3.times{n=n.zip(m=m.transpose.reverse).map{|i,j|i.zip(j).map &:sum}};n}

Спробуйте в Інтернеті!


1
Я впевнений , що ви можете замінити .map &:dupз *1відрізати багато символів. array*lengthстворює новий масив і є зручним способом дрібного клонування.
Уніхедрон

Насправді n=*mще коротше.
Unihedron

@Unihedron ось у чому проблема, мені потрібно глибоко клонуватись
Asone Tuhid

Мені здається, що це не впливає на вихід; Я познайомився з ним у вашому посиланні "спробуйте в Інтернеті", і висновок, схоже, залишається правильним при цій зміні
Unihedron

Ти маєш рацію, насправді тобі навіть не потрібен дрібний клон, transposeпро це піклується
Асона Тухід


1

Haskell , 84 83 67 байт

z=zipWith
e=[]:e
f l=foldr(\_->z(z(+))l.foldr(z(:).reverse)e)l"123"

Спробуйте в Інтернеті!

Дякуємо Лайконі та абсолютнолюдству за те, що зберегли багато байтів!



@totallyhuman Це розумно! Спасибі!
Крістіан Лупаску


1

Лушпиння , 9 байт

F‡+↑4¡(↔T

Спробуйте в Інтернеті!

Пояснення

F‡+↑4¡(↔T)  -- implicit input M, for example: [[1,0,1],[2,3,4],[0,0,2]]
     ¡(  )  -- repeat infinitely times starting with M  
        T   -- | transpose: [[1,2,0],[0,3,0],[1,4,2]]
       ↔    -- | reverse: [[1,4,2],[0,3,0],[1,2,0]]
            -- : [[[1,0,1],[2,3,4],[0,0,2]],[[1,4,2],[0,3,0],[1,2,0]],[[2,0,0],[4,3,2],[1,0,1]],[[0,2,1],[0,3,0],[2,4,1]],[[1,0,1],[2,3,4],[0,0,2]],…
   ↑4       -- take 4: [[[1,0,1],[2,3,4],[0,0,2]],[[1,4,2],[0,3,0],[1,2,0]],[[2,0,0],[4,3,2],[1,0,1]],[[0,2,1],[0,3,0],[2,4,1]]]
F           -- fold (reduce) the elements (example with [[1,0,1],[2,3,4],[0,0,2]] [[1,4,2],[0,3,0],[1,2,0]])
 ‡+         -- | deep-zip addition (elementwise addition): [[2,4,3],[2,6,4],[1,2,2]]
            -- : [[4,6,4],[6,12,6],[4,6,4]]

1

тинілісп , 132 байт

Візьмемо нещодавно додану функцію бібліотеки transposeдля віджимання!

(load library
(d T transpose
(d R(q((m #)(i #(c m(R(reverse(T m))(dec #)))(
(q((m)(foldl(q(p(map(q((r)(map sum(T r))))(T p))))(R m 4

Останній рядок - це неназвана лямбда-функція, яка виконує підсумовування обертання. Щоб насправді ним скористатися, вам потрібно скористатись, dщоб прив'язати його до імені. Спробуйте в Інтернеті!

Безумовно, з коментарями

(load library) (comment Get functions from the standard library)

(comment Rotating a matrix by 90 degrees is just transpose + reverse)
(def rotate
 (lambda (matrix)
  (reverse (transpose matrix))))

(comment This function recursively generates a list of (count) successive rotations
          of (matrix))
(def rotations
 (lambda (matrix count)
  (if count
   (cons matrix
    (rotations (rotate matrix) (dec count)))
   nil)))

(comment To add two matrices, we zip them together and add the pairs of rows)
(def matrix-add
 (lambda two-matrices
  (map row-sum (transpose two-matrices))))

(comment To add two rows of a matrix, we zip them together and add the pairs of numbers)
(def row-sum
 (lambda (two-rows)
  (map sum (transpose two-rows))))

(comment Our final function: generate a list containing four rotations of the argument
          and fold them using matrix-add)
(def rotated-sum
 (lambda (matrix)
  (foldl matrix-add (rotations matrix 4))))

1

Attache , 20 байт

Sum@MatrixRotate&0:3

Спробуйте в Інтернеті!

Пояснення

Sum@MatrixRotate&0:3

MatrixRotate&0:3розширюється, з вхідним сигналом x, MatrixRotate[x, 0:3]який в свою чергу exapnds до [MatrixRotate[x, 0], MatrixRotate[x, 1], MatrixRotate[x, 2], MatrixRotate[x, 3]]. Тобто вона векторизується над РЗЗ. Потім, Sumприймає суму всіх цих матриць на один рівень. Це дає бажаний результат.


1

Java 8, 135 133 байт

a->{int l=a.length,r[][]=new int[l][l],i=0,j;for(;i<l;i++)for(j=0;j<l;)r[i][j]=a[i][j]+a[j][l+~i]+a[l+~i][l-++j]+a[l-j][i];return r;}

-2 байти завдяки @ceilingcat .

Пояснення:

Спробуйте в Інтернеті.

a->{                        // Method with integer-matrix as both parameter and return-type
  int l=a.length,           //  Dimensions of the input-matrix
      r[][]=new int[l][l],  //  Result-matrix of same size
      i=0,j;                //  Index-integers
  for(;i<l;i++)             //  Loop over the rows
    for(j=0;j<l;)           //   Loop over the columns
      r[i][j]=              //    Set the cell of the result-matrix to:
              a[i][j]+a[j][l+~i]+a[l+~i][l-++j]+a[l-j][i];
                            //     The four linked cells of the input-matrix
  return r;}                //  Return the result-matrix
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.