Суммирование вращения


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)сохраняет два байта с "нормальным" вводом. Попробуйте онлайн!
Деннис

@ Денис Спасибо! Я думал, что lambda*lэто невозможно в Python 2 по какой-то причине.
г-н Xcoder

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

8

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

@(x)(y=x+rot90(x))+rot90(y,2)

Попробуйте онлайн!

объяснение

Это добавляет матрицу ввода с повернутой на 90 градусов версией самой себя. Результат затем добавляется с повернутой на 180 градусов версией самого себя.


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

Попробуйте онлайн!


Попытка номер три в Codegolf. От 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 байт благодаря Erik the Outgolfer (также благодаря предложению по исправлению ошибки).

Как?

ṚZ $ 3СS || Полная программа (монадическая).

   3Ð | || Сделайте это 3 раза и соберите результаты в списке
  $ || -> Применить последние две ссылки как монаду
Ṛ || –––> Обратный,
 Z || –––> Транспонировать.
      S || Суммирование.


2

APL (Dyalog Classic) , 17 байтов

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

Попробуйте онлайн!

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

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

-2 символа благодаря ngn

-2 символа, потому что составной оператор ∘, кажется, имеет приоритет над +

кажется, что roa повернуть на 90 °, 180a повернуть на 180 °, roa повернуть на 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"

решение будет pheraps 15 символов

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

Но может быть лучше один оператор, «составленный за время» d такой, что «3 df w» равно f (f (f (w))).

Сейчас я написал что-то, но оно слишком хрупкое без проверки типов.

Но мне больше нравится оператор q, который повторяет compose of 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 w w gw ggw gggw, ответ был бы + / ⌽⍉f 4 / rho w
RosLuP

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

В своем первом комментарии я предлагал этот поезд: ⊢ + ⌽∘⍉ + ⌽∘⊖ + ⍉∘⌽. Это может привести к еще более коротким решениям, если вы ловко переставляете загогулины и эффективно используете поезда.
НГН

@ngn даже простая {⍵ + ⍺} \ 1 2 3 4 ошибка возврата домена
RosLuP

2

K4 / K (ок) , 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

@ Униэдрон, вот в чем проблема, мне нужно глубоко клонировать
Asone Tuhid

Мне кажется, что это не влияет на результат; Я возился с этим в твоей ссылке «попробуй онлайн», и результат с
этими

Вы правы, на самом деле вам даже не нужен неглубокий клон, об этом transposeпозаботится
Asone Tuhid


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для привязки к имени. Попробуйте онлайн!

Ungolfed, с комментариями

(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

Атташе , 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]]. То есть он векторизуется над RHS. Затем 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.