旋转总和


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

每种语言中以字节为单位的最短代码获胜。强烈建议您进行说明!

Answers:


9

Python 2,78个字节

感谢Dennis为我以前的递归方法节省了两个字节。

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:通过将输入旋转90度3次并收集结果来生成所需的矩阵列表。然后,获取结果转置中每个矩阵的列之和。


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先生18年

您无法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度旋转

这会将加法运算符压缩到MX,以及Y和上Z,然后压缩结果。



5

朱莉娅0.6,29字节

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

在线尝试!

我无法接受LukeS的解决方案

但是在尝试时,我确实想到了这个,我认为这很可爱。

首先,我们将乘法重新定义为旋转操作,其中第一次是旋转次数。如此以来,由并列朱莉娅multipes然后:1xrotr90(x,1)3xrotr90(x,3)等。

然后我们写出总和。


5

朱0.628 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))因为这是在julia 0.6中声明1x1矩阵的方式。
Lyndon White


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在线上尝试一下

说明

我的八度答案的端口。

,        % 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

R69 64字节

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

在线尝试!


在codegolf尝试第三。从Giuseppe到69到64字节!


移动a到一个函数的参数将让您摆脱的保存字节{}左右的函数体。另外,移植Luis Mendo的Octave方法可能节省一些字节吗?最后,我不确定100%,但t(apply(x,2,rev))等于apply(x,1,rev)
朱塞佩

谢谢,我能够通过技巧1和技巧3进行改进。我没有通过添加参数来重复操作n来成功保存字节a()
Florian

1
我的意思是这样
Giuseppe



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

在线尝试!

感谢Outgolfer的Erik(也感谢修正错误的建议),节省了1个字节。

怎么样?

$ Z $3СS|| 完整程序(单声道)。

   3С|| 进行3次并在列表中收集结果
  $ || –>将最后两个链接作为单子应用
Ṛ|| –––>反向,
 Z || –––>移调。
      S || 求和。


2

APL(Dyalog Classic),17个字节

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

在线尝试!

APL NARS 34bytes 21 17个字符

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

-2个字符,感谢ngn

-2个字符,因为运算符Composite∘似乎优先于+

似乎⌽⍉a从90°旋转a,⌽⊖a从180°旋转a,⌽⍉⌽⊖a从270°旋转a

如果存在,则运算符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参数函数(monadic?),则它应该是:

"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

但是最好是一个运算符“组成n次” d,以使“ 3 df w”为f(f(f(w)))。

现在,我写了一些东西,但是如果没有类型检查,它太脆弱了。

但是我更喜欢用参数m重复f的运算符q(它不完整,因为没有写出类型的错误情况)

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可能正好⍉⌽,整件事都适合火车
ngn

如果存在一个f,这样gfwwww是w gw ggw gggw,答案将是+ /⌽⍉f4 / 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


知道有更好的方法来应用转换!
streetster

+ /(||:)\ tio.run/##y9bNz/7/X1tfo0bbSjPGWMFY2UjBVMFCwVjB0AhImQGhocH//wA可悲的是,... Gah无法弄清手机上的标记。
streetster

似乎注释中的标记存在错误,不仅在移动设备上-在反引号将事情弄乱之前先加反斜杠。我通过插入空格来避免它。
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

Ruby 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创建一个新数组,这是进行浅层克隆的一种便捷方法。
Unihedron

实际上,n=*m甚至更短。
Unihedron

@Unihedron就是问题,我需要深入克隆
Asone Tuhid

在我看来,它不会影响输出;我在您的“在线尝试”链接中
弄弄

您是对的,实际上您甚至不需要浅表克隆,都transpose可以解决这个问题
Asone Tuhid



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

tinylisp,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

最后一行是执行旋转求和的未命名lambda函数。要实际使用它,您将需要使用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

附件,20字节

Sum@MatrixRotate&0:3

在线尝试!

说明

Sum@MatrixRotate&0:3

MatrixRotate&0:3扩展为,具有输入xMatrixRotate[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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.