第一行和第一列的总和,然后第二行和第二列的总和……等等


31

以包含正整数的非空矩阵/数字数组作为输入。按此顺序返回第一行和第一列的总和,然后返回第二行和第二列的总和,直到没有更多行或列为止。

假设输入为:

2   10   10    2    4
9    7    7    2    9
1    7    6    2    4
7    1    4    8    9

然后输出应为:

45, 33, 16, 17

因为:2+9+1+7+10+10+2+4=45, 7+7+1+7+2+9=33, 6+4+2+4=16, 8+9=17

测试用例:

测试用例采用以下格式:

Input
---
Output

5
---
5
..........

1  4
----
5
..........

7
2
---
9
..........

 8    3    7   10    3    7   10    1
10    7    5    8    4    3    3    1
 1    6    4    1    3    6   10    1
 2    3    8    2    8    3    4    1
---
62   40   33   18
..........

30    39    48     1    10    19    28
38    47     7     9    18    27    29
46     6     8    17    26    35    37
 5    14    16    25    34    36    45
13    15    24    33    42    44     4
21    23    32    41    43     3    12
22    31    40    49     2    11    20
---
320  226   235   263   135    26    20
..........

7   10    1
4    4    2
6    3    4
1    4   10
5    7    6
---
34   20   20

作为数组:

[[5]]
[[1,4]]
[[7],[2]]
[[8,3,7,10,3,7,10,1],[10,7,5,8,4,3,3,1],[1,6,4,1,3,6,10,1],[2,3,8,2,8,3,4,1]]
[[30,39,48,1,10,19,28],[38,47,7,9,18,27,29],[46,6,8,17,26,35,37],[5,14,16,25,34,36,45],[13,15,24,33,42,44,4],[21,23,32,41,43,3,12],[22,31,40,49,2,11,20]]
[[7,10,1],[4,4,2],[6,3,4],[1,4,10],[5,7,6]]

这是因此每种语言中最短的解决方案将获胜。


2
@JonathanAllan,永远打印零有点困难,所以我想我必须拒绝。
Stewie Griffin

1
Retina程序可将漂亮的示例转换为Python数组。
mbomb007 '17

1
看例子。任务描述错误。第一个示例中10,7,7,1的第二列为,第二行为9,7,7,2,9,总和为59。依此类推
edc65 '17

1
@ edc65在示例中,似乎没有重用之前计算中使用的数字。换句话说,在考虑第n行时,仅使用第n列中的值,而忽略第1至n-1列中的值。
布赖恩J

1
@ Arc676标准io规则。函数参数是可接受的输入方法之一。
Stewie Griffin's

Answers:


10

MATL,16字节

&n:w:!XlX:GX:1XQ

在线尝试!验证所有测试用例

说明

以输入为例

2   10   10    2    4
9    7    7    2    9
1    7    6    2    4
7    1    4    8    9

该代码&n:w:!Xl构建了列向量[1; 2; 3; 4]和行向量[1 2 3 4 5]。然后Xl用广播计算最小元素明智,这给出了矩阵

1 1 1 1 1
1 2 2 2 2
1 2 3 3 3
1 2 3 4 4

X:将此矩阵线性化(按列顺序)到列向量中[1; 1; 1; 1; 1; 2; 2; ... ; 4]。将该向量和作为线性化的输入矩阵,GX:作为输入传递给accumarray(... @sum)函数或1XQ。这将计算第二输入的总和,并按第一输入的值分组。



5

CJam23 18字节

{[{(:+\z}h;]2/::+}

匿名块在堆栈上保留参数,并将结果保留在堆栈上。

在线尝试!

说明

[      e# Begin working in an array.
 {     e#  Do:
  (:+  e#   Remove the first row of the matrix and sum it.
  \z   e#   Bring the matrix back to the top and transpose it.
 }h    e#  While the matrix is non-empty.
 ;     e#  Discard the remaining empty matrix.
]      e# Close the array.
2/     e# Split it into consecutive pairs of elements (possibly with a singleton on the end).
::+    e# Sum each pair.

这不是有点“作弊”吗?我的意思是,您没有在字节数中计算输入和输出代码。对于输入和输出,它仅长1个字节:q~[{(:+\z}h;]2/::+p
FrodCube

@FrodCube它由meta共识允许。
Business Cat

2
实际上,从技术上讲,它与完整程序的长度相同,因为我可以省略开头[。但作为一个块,我认为我需要它,因为它也不必捕获下面的整个堆栈。
Business Cat

5

05AB1E14 11字节

[ćOˆøŽ]¯2ôO

在线尝试!

说明

[   Ž ]       # loop until stack is empty
 ć            # extract the head
  Oˆ          # sum and add to global list
     ø        # transpose
       ¯      # push global list
        2ô    # split into pairs
          O   # sum each pair

4

JavaScript(ES6),60个字节

a=>a.map((b,y)=>b.map((c,x)=>r[x=x<y?x:y]=~~r[x]+c),r=[])&&r

天真的解决方案,可能是更好的方法。


4

Mathematica,60个字节

灵感来自路易斯·门多Luis Mendo)的MATL答案

Pick[#,Min~Array~d,n]~Total~2~Table~{n,Min[d=Dimensions@#]}&

说明:Min~Array~Dimensions@#构造如下矩阵:

1 1 1 1 1
1 2 2 2 2
1 2 3 3 3
1 2 3 4 4

然后,Pick[#,...,n]~Total~2选择与n上面的怪异矩阵中的数字相对应的输入矩阵的项,并对它们求和。最后...~Table~{n,Min[d=Dimensions@#]}遍历n

这比朴素的方法短了1个字节:

{#[[n,n;;]],#[[n+1;;,n]]}~Total~2~Table~{n,Min@Dimensions@#}&

4

Haskell,50个 49字节

f(a@(_:_):b)=sum(a++map(!!0)b):f(tail<$>b)
f _=[]

在线尝试!

如果至少有一行包含至少一个元素,则结果为第一行与所有其他行的开头的总和,然后是与所有其他行的结尾的递归调用。在所有其他情况下,结果均为空列表。

编辑:ØrjanJohansen保存了一个字节。谢谢!


4

八度64 52字节

感谢@StewieGriffin节省了1个字节!

@(x)accumarray(min((1:size(x))',1:rows(x'))(:),x(:))

这定义了一个匿名函数。

在线尝试!

说明

该代码类似于我的MATL答案(请参阅此处的说明)。

利用行为与相同的事实,使用1:size(x)代替了保存两个字节。另外,感谢Stewie,使用代替了保存了一个字节。1:size(x,1)1:[a b]1:a1:rows(x')1:size(x,2)


3

k,19个字节

|1_-':|+//'(1_+1_)\

在线尝试!

说明:

           (1_+1_)   /a function that strips the top and leftmost rows of a matrix
                  \  /apply this function as many times as possible,
                     /    saving each result as one element of a list
       +//'          /for each result, get the sum of all numbers
|  -':|              /subtract every right value from every left value
 1_                  /remove the extra 0

3

05AB1E,16个字节

[ćOsø.g<NQ#])2ôO

在线尝试!尝试所有测试

[                # Start loop
 ć               # Extract first element
  O              # Sum
   sø            # Transpose the input array (without the first N rows and columns)
     .g<NQ       # Push if (stack height - 1 == loop count)
          #]     # If they were equal break
            )2ô  # Break stack into chunks of 2
               O # Sum the chunks

3

八度63 60字节

@(A)(@(L)sum(triu(A,1)')(L)+sum(tril(A))(L))(1:min(size(A)))

在线尝试!

此矩阵的答案:

2   10   10    2    4
9    7    7    2    9
1    7    6    2    4
7    1    4    8    9

是其上三角部分的行总和的向量:

0   10   10    2    4
0    0    7    2    9
0    0    0    2    4
0    0    0    0    9

加上其下三角部分的列总和的向量:

2    0    0    0    0
9    7    0    0    0
1    7    6    0    0
7    1    4    8    0

这正是我的答案是计算。


2

朱莉娅 62字节

f=x->1∈size(x)?sum(x):(n=f(x[2:end,2:end]);[sum(x)-sum(n);n])

通过求和整个矩阵,然后减去下一个块的总和,以递归方式工作。可能不是最有效的方法,但很直观。


2

Java 7,248字节

String c(int[][]a){int l=a.length,L=a[0].length,b[][]=new int[l][L],i,j,x=1,s;for(;x<(l>L?l:L);x++)for(i=l;i-->x;)for(j=L;j-->x;b[i][j]=x);String r="";for(;x-->0;r=s>0?s+" "+r:r)for(s=0,i=0;i<l;i++)for(j=0;j<L;j++)s+=b[i][j]==x?a[i][j]:0;return r;}

在这里尝试。

一般说明:

假设输入数组的尺寸为4x6。代码的第一部分将创建一个临时矩阵,并按如下所示进行填充:

// 1. Fill the entire array with 0:
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0

// 2. Overwrite the inner part with 1 (excluding the first row & column):
0 0 0 0 0 0
0 1 1 1 1 1
0 1 1 1 1 1
0 1 1 1 1 1

// #. Etc. until we are left with this:
0 0 0 0 0 0
0 1 1 1 1 1
0 1 2 2 2 2
0 1 2 3 3 3

在代码的第二部分中,它将在该温度矩阵上循环,并为该温度矩阵中每个不同的数字求和输入矩阵的所有值。

代码说明:

String c(int[][]a){               // Method with int-matrix parameter and String return-type
  int l=a.length,                 //  Amount of rows
      L=a[0].length,              //  Amount of columns
      b[][]=new int[l][L],        //  New temp matrix to fill as explained above
      i,j,x=1,s;                  //  Some temp integers

                                  //This is the first part of the code mentioned above:
  for(;x<(l>L?l:L);x++)           //  Loop (1) over the rows or columns (whichever is highest)
    for(i=l;i-->x;)               //   Inner loop (2) over the rows
      for(j=L;j-->x;              //    Inner loop (3) over the columns
        b[i][j]=x);               //     Set the current `x`-number
                                  //    End of loop (3) (implicit / no body)
                                  //   End of loop (2) (implicit / single-line body)
                                  //  End of loop (1) (implicit / single-line body)

                                  //This is the second part of the code mentioned above:
  String r="";                    //  Result-String
  for(;x-->0;                     //  Loop (4) over the unique numbers in the temp matrix
             r=s>0?s+" "+r:r)     //   After every iteration, append the sum to the result (if it's larger than 0)
    for(s=0,i=0;i<l;i++)          //   Inner loop (5) over the rows (and reset the sum to 0)
      for(j=0;j<L;j++)            //    Inner loop (6) over the columns
        s+=b[i][j]==x?a[i][j]:0;  //     Add to the sum if its position equals the current `x` in the temp matrix
                                  //    End of loop (6) (implicit / single-line body)
                                  //   End of loop (5) (implicit / single-line body)
                                  //  End of loop (4) (implicit / single-line body)
  return r;                       //  Return the result-String
}                                 // End of method

2

Perl 6的63 55个字节

{($_ Z [Z] $_).kv.map(->\a,\b{b.flatmap(*[a..*]).sum -b[0;a]})}

{($_ Z [Z] .skip).kv.map({$^b.flatmap(*[$^a..*]).sum})}
  • $_ 是匿名函数的矩阵输入
  • .skip 是删除了第一行的输入矩阵
  • [Z] .skip是除去第一行的输入矩阵的转置;也就是说,没有第一列的转置
  • $_ Z [Z] .skip 用其Transpose-sans-first-column压缩输入矩阵,产生一个列表 ((first-row, first-column-sans-first-element), (second-row, second-column-sans-first-element), ...)
  • .kv 给每对加上索引
  • map({...})使用一个函数获取一对对的映射,该函数接受第一个参数(索引)$^a作为第二个参数(行/列对)作为第二个参数$^b
  • $^b.flatmap(*[$^a..*]).sum去除$^a每个行/列对的第一个元素,然后将所有剩余的元素相加

经过一番思考,我意识到像在我的第一个解决方案中一样,在压缩之前剥离转置的第一列等同于减去双倍对角元素。这让我删除了该减法,并且仅对映射函数使用了每个参数一次,这使得{...$^a...$^b...}将参数传递给匿名函数的方法比原始方法更有效-> \a, \b {...a...b...}


1

Vim,66,52字节

qq^f j<C-v>}dkV}Jo<esc>p@qq@q:%s/\v> +</+/g|%norm C<C-v><C-r>=<C-v><C-r>"<C-v><cr><cr>

在线尝试!

错误的工作工具...


1

果冻,10 字节

Ḣ;Ḣ€SṄȧßS¿

完整的程序可以打印值

在线尝试!

怎么样?

Ḣ;Ḣ€SṄȧßF¿ - Main link: list of lists a
Ḣ          - head a (pop the first row and yield it, modifying a)
  Ḣ€       - head €ach (do the same for each of the remaining rows)
 ;         - concatenate
    S      - sum (adds up the list that contains the top row and left column)
     Ṅ     - print that plus a linefeed and yield the result
         ¿ - while:
           - ... condition:
        F  -   flatten (a list of empty lists flattens to an empty list which is falsey) 
           - ... body:
       ß   -   call this link with the same arity (as a monad) i.e. Main(modified a)
      ȧ    - logical and (when the sum is non-zero gets the modified a to feed back in)

1

Python + NumPy,75个字节

输入是2D numpy数组。

lambda L:[sum(L[i,i:])+sum(L[i+1:,i])for i in range(min(len(L),len(L[0])))]

在线尝试



1

Pyth,16 15字节

.es+>b+1k>@CQkk

获取数字数组的python样式数组,返回和数组。

试试吧!

说明

.es+>b+1k>@CQkk 
.e             Q  # Enumerated map over the implicit input (Q); indices k, rows b
           CQ     # Take the transpose
          @  k    # The kth column
         >    k   # cut off the first k elements
    >b+1k         # cut off the first k+1 elements of the rows, so (k,k) isn't counted twice
  s+              # add the row and column together and sum

1

GNU APL 1.7,123字节

解决方案需要两个函数:一个函数创建一个全局数组,然后调用第二个函数,该函数将总和递归地附加到该数组。

∇f N
R←⍬
g N
R
∇
∇g N
→2+2×0∈⍴N
R←R,(+/N[1;])+(+/N[;1])-N[1;1]
g N[1↓⍳1⊃⍴N;1↓⍳2⊃⍴N]
∇

开始和结束功能。二者fg采取表作为参数(基本上二维阵列)。这些可以用创建X←rows cols ⍴ 1 2 3 4...

R←⍬ 将空向量分配给全局变量 R

g N 使用与第一个函数相同的参数调用第二个函数。

⍴N给出的尺寸N; 当维度之一为零时,没有更多的行/列加起来。0∈⍴N如果尺寸为零,则返回1。→2+2×0∈⍴N分支到行号2加该函数的返回值的2倍:如果不为零,则返回0,然后该函数分支到行2(下一行)。如果有零,返回1和功能分支到第4行(该函数结束,所以return基本上)。

/是reduce运算符。它将左运算符(运算符(+))应用于列表中作为右参数给出的每个元素。N[1;]给出表的整个第一行并N[;1]给出第一列。(+/N[1;])+(+/N[;1])-N[1;1]将第一行和第一列的总和相加,并减去左上角的值,因为它被同时添加到列总和和行总和中。R←R,...将新计算的值附加到全局向量R

然后,函数调用自身(递归直到没有更多的行或列)。在拾取操作获得从列表中指定的元素。1⊃⍴N给出行2⊃⍴N数,列数。给出从1到指定数字的所有数字。该降运算符可以从列表的开头元素。如果在访问表或向量中的元素(例如N[1 2 3])时给出多个索引,则APL会访问每个索引。因此,1↓⍳1⊃⍴N给出除第一个(2, 3, 4, ..., N)以外的每一行的索引,并1↓⍳2⊃⍴N给出相似的向量,但列数相同。g N[1↓⍳1⊃⍴N;1↓⍳2⊃⍴N]再次调用该函数,但没有第一行或第一列。



0

Mathematica,116个字节

l=Length;If[l@#==1||l@#[[1]]==1,Total@Flatten@#,Total/@Flatten/@Table[{#[[i]][[i;;]],#[[All,i]][[i+1;;]]},{i,l@#}]]&

输入表格

[{{5}},[{{1},{4}}],[{{7,2}}]或[{{....},{....} ... {。 ...}}]


0

Clojure,98个字节

#(vals(apply merge-with +(sorted-map)(mapcat(fn[i r](map(fn[j v]{(min i j)v})(range)r))(range)%)))

使用行和列索引对输入进行迭代(以非常冗长的方式),创建一个以ij为最小值的哈希图,并将其与键合并,将哈希图合并+为排序图,并返回值。


0

R,102字节

function(x)`for`(i,1:min(r<-nrow(x),k<-ncol(x)),{dput(sum(x[,1],x[1,-1]));x=matrix(x[-1,-1],r-i,k-i)})

返回一个匿名函数;用结尾的换行符将结果打印到控制台。我可能需要其他方法。

遍历最少的行和列;打印x[,1](第一列)和x[1,-1]第一行的和(除第一项外),然后设置x为等于x[-1,-1](即,x排除其第一行和第一列)的矩阵。不幸的是,x=x[-1,-1]在平方矩阵的情况下,简单地设置会导致设置失败,因为x为2x2时,子设置会返回一个向量而不是矩阵。

在线尝试!


0

Java 7中,280个 276字节

import java.util.*;String d(ArrayList l){String r="";for(;l.size()>0&&((List)l.get(0)).size()>0;l.remove(0))r+=s(l)+" ";return r;}int s(List<ArrayList<Integer>>l){int s=0,L=l.size(),i=1;for(;l.get(0).size()>0;s+=l.get(0).remove(0));for(;i<L;s+=l.get(i++).remove(0));return s;}

在这里尝试。

我以前的答案相比的替代方法使用数组的这种替代方法最终还比这个短(所以我有点浪费时间尝试这种替代方法)。

一般说明:

@Riley令人惊叹的05AB1E答案的启示
此答案使用一个列表,在计算出每个和后,它将从列表矩阵中删除第一列和第一行,如下所示:

// Starting matrix:
7 10 1
4 4  2
6 3  4
1 4  10
5 7  6

// After first iteration (result so far: "34 "):
4  2
3  4
4  10
7  6

// After second iteration (result so far: "34 20 "):
4
10
6

// After last iteration, result: "34 20 20 "

代码说明:

import java.util.*;                // Required import for List and ArrayList

String d(ArrayList l){             //  Method with ArrayList parameter and String return-type
  String r="";                     //  Return-String
  for(;l.size()>0&&((List)l.get(0)).size()>0; 
                                   //  Loop as long as the list still contains anything
       l.remove(0))                //  And remove the first row after every iteration
    r+=s(l)+" ";                   //   Append the sum to the result-String
                                   //  End of loop (implicit / single-line body)
  return r;                        //  Return result-String
}                                  // End of method

int s(List<ArrayList<Integer>>l){  // Separate method with List-matrix parameter and integer return-type
  int s=0,                         //  The sum
      L=l.size(),                  //  The size of the input list
      i=1;                         //  Temp integer
  for(;l.get(0).size()>0;          //  Loop (1) over the items of the first row
    s+=l.get(0).                   //   Add the number to the sum
                remove(0)          //   And remove it from the list afterwards
  );                               //  End of loop (1)
  for(;i<L;                        //  Loop (2) over the rows
    s+=l.get(i++).                 //   Add the first number of the row to the sum
                  remove(0)        //   And remove it from the list afterwards
  );                               //  End of loop (2)
  return s;                        //  Return sum
}                                  // End of separate method

0

Python,93个字节

类似于mbomb007的答案,但没有NumPy

f=lambda m:[sum(m[k][k:])+sum(list(zip(*m))[k][k+1:])for k in range(min(len(m),len(m[0])))]
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.