每个维度的总和


20

您将获得一个多维整数数组。每个尺寸都有固定的尺寸(因此,如果尺寸为2D,则始终为矩形)。您的程序应计算每个维度中的总和,并将该总和作为该维度中新的最后一项附加。

假设输入和输出数组为A和B,并且A 的维度i的大小为n i。B将具有与A相同的维数,并且维i的大小将为n i +1。B j 1,j 2,...,j m是A k 1,k 2,...,k m的和,其中:

  • ķ = j的如果j <= N
  • 如果j i = n i +1 则0 <k i <= n i

对于输入:

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

您的程序(或函数)应输出:

[[1 2 3 6]
 [4 5 6 15]
 [5 7 9 21]]

输入仅包含数组。输入中提供维度总数和每个维度的大小。(但是您可以通过自己的代码从数组中获取它们。)您可以使用任何方便的语言列表格式,只要它不直接指定尺寸数或尺寸大小即可。

输入具有至少1个维度,并且数组中至少有1个项目。

这是代码高尔夫球。最短的代码胜出。

测试用例

Input:
[5 2 3]
Output:
[5 2 3 10]

Input:
[[1 2 3] [4 5 6]]
Outputs:
[[1 2 3 6] [4 5 6 15] [5 7 9 21]]

Input:
[[[1] [1] [1] [0]]]
Output:
[[[1 1] [1 1] [1 1] [0 0] [3 3]] [[1 1] [1 1] [1 1] [0 0] [3 3]]]

Input:
[[[[-1]]]]
Output:
[[[[-1 -1] [-1 -1]] [[-1 -1] [-1 -1]]] [[[-1 -1] [-1 -1]] [[-1 -1] [-1 -1]]]]

您会发布该16字节APL解决方案吗?如果不愿意,可以吗?
丹尼斯

@Dennis您应该发布它。
jimmy23013 2015年

Answers:


9

J,14个字节

#@$(0|:],+/^:)

用法:

   ]a=.i.2 3
0 1 2
3 4 5

   (#@$(0|:],+/^:)) a    NB. parens are optional
0 1 2  3
3 4 5 12
3 5 7 15

该功能等效于以下功能,(0|:],+/)^:(#@$)但使用用户定义的副词来保存括号。

从右到左解释后面的代码:

  • ^:(#@$)重复尺寸^:数量:#$

    • ],+/,将参数]与最后一个维度的和连接在一起+/
    • 0|:|:通过将第一个放在0尺寸列表的末尾来旋转尺寸
  • 完成上述步骤后,我们将获得原始输入以及所有维度上的总和。

对于我较旧的解决方案,请检查修订历史记录。

在这里在线尝试。


15

Mathematica,32个 20字节

#/.List->({##,+##}&)&

例:

In[1]:= #/.List->({##,+##}&)&[{{1, 2, 3}, {4, 5, 6}}]

Out[1]= {{1, 2, 3, 6}, {4, 5, 6, 15}, {5, 7, 9, 21}}

说明:

的完整格式{{1, 2, 3}, {4, 5, 6}}List[List[1, 2, 3], List[4, 5, 6]]。然后用List函数替换表达式中的所有({##,+##}&)


10

Python 2,95个字节

from numpy import*
a=copy(input())
for d in r_[:a.ndim]:a=r_[`d`,a,sum(a,d,keepdims=1)]
print a

这会遍历每个维度,并使用NumPy合并其总和。

我偶然发现了NumPy's r_,这对于高尔夫来说真是太棒了。r_[:n]range(n)更短(更强大)(例如r_[:4, 7, 8, 10:100:10])短。它还可以做其他事情,例如沿任意轴进行串联。

用法示例:

$ python sum.py
[[1, 2, 3], [4, 5, 6]]
[[ 1  2  3  6]
 [ 4  5  6 15]
 [ 5  7  9 21]]

7

APL,16 15字节

{×≡⍵:∇¨⍵,+/⍵⋄⍵}

感谢@ user23013精打细算的3个字节并找出正确的输入格式。

使用TryAPL在线验证测试用例。

理念

总体思路与我的CJam提交中的思路相同,APL允许更短的实现时间。它仅包含两个步骤:

  1. 对数组的最大维度求和。

  2. 对每个子数组重复步骤1。

{             } ⍝ Define a monadic function with argument ⍵ and reference ∇.
 ×≡⍵:           ⍝ If the depth of ⍵ is positive:
     ∇          ⍝   Apply this function...
      ¨         ⍝   to each element of...
       ⍵,       ⍝   the concatenation of ⍵...
         +/⍵    ⍝   and the sum across ⍵.
            ⋄⍵  ⍝  Else, return ⍵.

只是弄清楚了原始代码的输入格式:,⊂(,1)(,1)(,1)(,0),⊂,⊂,⊂,¯1。因此,您可以删除另一个字符。
jimmy23013

2
@ user23013:所以我的代码确实起作用了!您必须喜欢一种编程语言,在该语言中,输入格式比实际代码更难正确……
Dennis

6

18 15字节

{a-a?fMaAE$+aa}

这是一个匿名函数,它将数组作为参数并返回结果。调用示例,使用该-p标志获取可读的输出:

C:\> pip.py -pe "( {a-a?fMaAE$+aa} [[1 2 3] [4 5 6]] )"
[[1;2;3;6];[4;5;6;15];[5;7;9;21]]

尽管是独立派生,但该想法与Dennis的APL基本相同。进一步来说:

{             }  Define a lambda function with parameter a
 a-a?            Shortest way I could find to test whether the argument is a list
                 or scalar: subtracting a number from itself gives 0 (falsy);
                 subtracting a list from itself gives a list of zeros (truthy!)
     fM          If truthy, it's a list, so map the same function (f) recursively to:
       aAE         Argument, with appended element...
          $+a      ...sum of argument (fold on +)
             a   If falsy, it's a scalar, so just return it

该方法之所以有效,是因为+(以及许多其他运算符)在Pip中的列表上逐项起作用-这一功能受APL等数组编程语言的启发。因此,当您$+输入像这样的列表时[[1 2 3] [4 5 6]],结果将是[5 7 9]所需的。在列表或标量测试还用于:[1 2 3] - [1 2 3]给出[0 0 0],这是truthy(如同除了空列表中的所有列表)。

以前的18字节版本:

{Ja=a?a(fMaAE$+a)}

变化:

  1. 在标量或列表测试中保存了一个字节-先前的方法是连接参数(在空字符串上)并测试是否等于其未连接的self(因为起作用[1 2 3] != 123);
  2. 消除了括号。它们在原始文件中是必需的,因为M它的优先级低于?(尽管我可能要更改它的优先级,尤其是现在):没有它们,代码将被解析为(Ja=a?af)M(aAE$+a),从而导致奇怪的错误消息。但是,三元运算符的中间参数可以是任何优先级的任何表达式,不需要括号。因此,通过使列表成为真实情况,我可以保存这两个字节。

2
那是一门有趣的语言。在CJam和Pyth中缺少逐项运算符。
丹尼斯

@丹尼斯谢谢!这项工作仍在进行中,但可以完成一些任务。
DLosc

5

APL(25)

{N⊣{N,[⍵]←+/[⍵]N}¨⍳⍴⍴N←⍵}

APL的数组具有内置维,因此此函数采用n维数组,然后沿每个维求和。

      {N⊣{N,[⍵]←+/[⍵]N}¨⍳⍴⍴N←⍵} ↑(1 2 3)(4 5 6)
1 2 3  6
4 5 6 15
5 7 9 21

说明:

  • N←⍵:将数组存储在中N
  • ⍴⍴N:获取尺寸的数量N。(给出尺寸,即⍴↑(1 2 3)(4 5 6)给出2 3,因此⍴⍴给出尺寸。)
  • {... }¨⍳:从1到⍴⍴N:的 每个数字
    • +/[⍵]NN沿维度求和
    • N,[⍵]←:将结果加入该N维度
  • N:最后,返回N

如果数组包含单例,我似乎无法使这项工作。对于第三或第四个测试用例,您将如何调用此函数?
丹尼斯

3
@Dennis:您需要向函数传递多维数组。的↑(1 2 3)(4 5 6)作用是简单地使用从2个1维数组构造2维数组。它不是内置符号,也没有概括您的思维方式。构造第三个和第四个数组的规范方法是1 4 1⍴1 1 1 01 1 1 1⍴¯1,但是也可以在不参考大小的情况下构造它们,例如,第三个数组也可以用构建↑⍉⍪(,1)(,1)(,1)(,0),第四个数组可以用构建↑⍪⊂⍪¯1
marinus

好的,这说明了一切。我朴素的递归方法实现对我认为是数组(例如f←{0=≡⍵:⍵⋄f¨⍵,+/⍵}⋄f((1 2)(3 4))((5 6)(7 8)))的效果很好,但是似乎嵌套的向量和数组是不同的,并且前者不能将标量与单例区分...
丹尼斯2015年

2
@丹尼斯高尔夫:{×≡⍵:∇¨⍵,+/⍵⋄⍵}((1 2)(3 4))((5 6)(7 8))。固定:{×⍴⍴⍵:∇↓⍵,+/⍵⋄⍵}1 4 1⍴1 1 1 0。现在比Mathematica还短...
jimmy23013

3

CJam,36个字节

{_`{'[<}#:D{_":"D'.e]'++~a+{S}%}&}:S

这是一个递归的命名函数,它从堆栈中弹出一个数组,然后返回一个。

尝试在 CJam解释器中

理念

可悲的是,CJam没有自动加运算符的操作,可以添加任意嵌套的数组,因此我们必须自己实现它。幸运的是,它完成了两个infix运算符:(reduce)和.(vectorize),将对完成此任务有所帮助。

第一步是计算维数。这很容易:将数组转换为字符串表示形式,并计算前导[的数量。

现在,要减少一维数组,通常只需执行:+

[1 2] :+ e# Pushes 3.

对于二维数组,+将执行级联而不是加法运算,因此我们必须对其向量化:

[[1 2][3 4]] :.+ Pushes [4 6].

现在,对于三维数组,.+将对二维数组进行运算并再次执行级联。这次,我们必须向量化.+

[[[1 2][3 4]][[5 6][7 8]]] :..+ e# Pushes [[[6 8] [10 12]]].

对于一般的情况下,尺寸的阵列d,我们必须链中的一个:d - 1 .的和一种+

当然,这仅对数组的最大维度求和。我们可以通过定义一个函数S来解决此问题,该函数计算维数(如果为零,则不执行任何操作),执行如上所述的求和,最后将自身应用于数组的元素。

{                                }:S e# Define S:
 _`                                  e#   Push a string representation of a the array.
   {'[<}#                            e#   Find the index of the first non-bracket.
         :D                          e#   Save it in D.
           {                   }&    e#   If D is positive:
            _                        e#     Push a copy of the array.
             ":"D'.e]                e#     Pad ":" with "."s to a string of length D.
                     '++~            e#     Add a "+" to the string and evaluate.
                         a+          e#     Wrap the result in a array and concatenate.
                           {S}%      e#     Apply S to the elements of the array.

2

红宝石(181个 139 119个 108字节)

def d a;a.push a[0].to_s['[']?a.map{|x|d x}.transpose.map{|x|x.reduce:+}:a.reduce(:+)end
p d eval ARGF.read

假设输入作为JSON传递。


实际上,您可以编写一个接受已解析数组的函数并返回一个数组,并且d在此答案中仅计入95个字节。
jimmy23013

2

Java,669字节

不会撒谎,我为此感到很自豪:p

import java.lang.reflect.Array;enum S{D;<A>A s(A a){int l=Array.getLength(a),x=0;Class t=a.getClass();Class c=t.getComponentType();A r=(A)Array.newInstance(c,l+1);System.arraycopy(a,0,r,0,l);if(t==int[].class)for(;x<l;)((int[])r)[l]=((int[])r)[l]+((int[])r)[x++];else{for(;x<l;)Array.set(r,x,S.this.s(Array.get(r,x++)));Object o=Array.get(r,0);for(;--x>0;)o=s(o,Array.get(r,x));Array.set(r,l,o);}return r;}<A>A s(A a,A b){int l=Array.getLength(a),x=0;Class t=a.getClass();A r=(A)Array.newInstance(t.getComponentType(),l);if(int[].class==t)for(;x<l;)((int[])r)[x]=((int[])a)[x]+((int[])b)[x++];else for(;x<l;)Array.set(r,x,s(Array.get(a,x),Array.get(b,x++)));return r;}}

通过测试扩展:

import java.lang.reflect.Array;
import java.util.Arrays;

public enum SumOf{
    Dimensions;

    <A>A sum(A array){ //call this method to solve the challenge
        int length=Array.getLength(array),x=0;
        Class arrayType=array.getClass();
        Class componentType=arrayType.getComponentType();
        //grow the array to include the sum element
        A result=(A)Array.newInstance(componentType,length+1);
        System.arraycopy(array,0,result,0,length);
        if(arrayType==int[].class) //one-dimensional array needs to be handled separately
            for(;x<length;) //find the sum
                ((int[])result)[length]=((int[])result)[length]+((int[])result)[x++];        
        else{ //multi-dimensional array
            for(;x<length;) //find the sum for each element in this dimension's array
                Array.set(result,x,sum(Array.get(result,x++)));
            //find the total sum for this dimension's array
            Object s=Array.get(result,0);
            for(;--x>0;)
                s=_sum(s,Array.get(result,x)); //add the 2 elements together
            Array.set(result,length,s);
        }
        return result;
    }

    <A>A _sum(A arrayA,A arrayB){ //this method is used by the previous method
        int length=Array.getLength(arrayA),x=0;
        Class arrayType=arrayA.getClass();
        A result=(A)Array.newInstance(arrayType.getComponentType(),length);
        if(int[].class==arrayType) //one-dimensional array needs to be handled separately
            for(;x<length;) //find the sum of both arrays
                ((int[])result)[x]=((int[])arrayA)[x]+((int[])arrayB)[x++];
        else
            for(;x<length;) //find the sum of both arrays
                Array.set(result,x,sum(Array.get(arrayA,x),Array.get(arrayB,x++)));
            return result;
        }

    static int[] intArray( int firstElement, int...array ) {
        if( array == null ) array = new int[0];
        array = Arrays.copyOf( array, array.length + 1 );
        System.arraycopy( array, 0, array, 1, array.length - 1 );
        array[0] = firstElement;
        return array;
    }

    static <E> E[] arrayArray( E firstElement, E...array ) {
        if( array == null ) array = (E[]) Array.newInstance( firstElement.getClass(), 0 );
        array = Arrays.copyOf( array, array.length + 1 );
        System.arraycopy( array, 0, array, 1, array.length - 1 );
        array[0] = firstElement;
        return array;
    }

    static void printIntArray( int[]array ){
        System.out.print("[ ");
        for( int x = 0; x < array.length; x++ )
            System.out.print( array[x] + " " );
        System.out.print("] ");
    }

    static < A > void printArray( A array ) {
        if( array.getClass() == int[].class ){
            printIntArray( (int[]) array );
        }
        else {
            System.out.print("[ ");
            int length = Array.getLength( array );
            for( int x = 0; x < length; x++ )
                printArray( Array.get( array, x ) );
            System.out.print("] ");
        }
    }

    public static void main(String[]s){
        int[] test01 = intArray( 5, 2, 3 );
        System.out.print("Input: ");
        printArray( test01 );
        System.out.print("\nOutput: ");
        printArray( SumOf.Dimensions.sum( test01 ) );
        System.out.println();

        int[][] test02 = arrayArray( intArray( 1, 2, 3 ), intArray( 4, 5, 6 ) );
        System.out.print("\nInput: ");
        printArray( test02 );
        System.out.print("\nOutput: ");
        printArray( SumOf.Dimensions.sum( test02 ) );
        System.out.println();

        int[][][] test03 = arrayArray( arrayArray( intArray( 1 ), intArray( 1 ), intArray( 1 ), intArray( 0 ) ) );
        System.out.print("\nInput: ");
        printArray( test03 );
        System.out.print("\nOutput: ");
        printArray( SumOf.Dimensions.sum( test03 ) );
        System.out.println();

        int[][][][] test04 = arrayArray( arrayArray( arrayArray( intArray( -1 ) ) ) );
        System.out.print("\nInput: ");
        printArray( test04 );
        System.out.print("\nOutput: ");
        printArray( SumOf.Dimensions.sum( test04 ) );
        System.out.println();

        int[][][] test05 = arrayArray( arrayArray( intArray( 1, 2, 3 ), intArray( 4, 5, 6 ), intArray( 7, 8, 9 ) ), arrayArray( intArray( 11, 12, 13 ), intArray( 14, 15, 16 ), intArray( 17, 18, 19 ) ), arrayArray( intArray( 21, 22, 23 ), intArray( 24, 25, 26 ), intArray( 27, 28, 29 ) ) );
        System.out.print("\nInput: ");
        printArray( test05 );
        System.out.print("\nOutput: ");
        printArray( SumOf.Dimensions.sum( test05 ) );
        System.out.println();
    }

}

运行扩展的测试版本将显示以下内容:

Input: [ 5 2 3 ] 
Output: [ 5 2 3 10 ] 

Input: [ [ 1 2 3 ] [ 4 5 6 ] ] 
Output: [ [ 1 2 3 6 ] [ 4 5 6 15 ] [ 5 7 9 21 ] ] 

Input: [ [ [ 1 ] [ 1 ] [ 1 ] [ 0 ] ] ] 
Output: [ [ [ 1 1 ] [ 1 1 ] [ 1 1 ] [ 0 0 ] [ 3 3 ] ] [ [ 1 1 ] [ 1 1 ] [ 1 1 ] [ 0 0 ] [ 3 3 ] ] ] 

Input: [ [ [ [ -1 ] ] ] ] 
Output: [ [ [ [ -1 -1 ] [ -1 -1 ] ] [ [ -1 -1 ] [ -1 -1 ] ] ] [ [ [ -1 -1 ] [ -1 -1 ] ] [ [ -1 -1 ] [ -1 -1 ] ] ] ] 

Input: [ [ [ 1 2 3 ] [ 4 5 6 ] [ 7 8 9 ] ] [ [ 11 12 13 ] [ 14 15 16 ] [ 17 18 19 ] ] [ [ 21 22 23 ] [ 24 25 26 ] [ 27 28 29 ] ] ] 
Output: [ [ [ 1 2 3 6 ] [ 4 5 6 15 ] [ 7 8 9 24 ] [ 12 15 18 45 ] ] [ [ 11 12 13 36 ] [ 14 15 16 45 ] [ 17 18 19 54 ] [ 42 45 48 135 ] ] [ [ 21 22 23 66 ] [ 24 25 26 75 ] [ 27 28 29 84 ] [ 72 75 78 225 ] ] [ [ 33 36 39 108 ] [ 42 45 48 135 ] [ 51 54 57 162 ] [ 126 135 144 405 ] ] ] 

扩展版本的erm,代码行:Array.set(result,x,sum(Array.get(arrayA,x),Array.get(arrayB,x ++)))); 在_sum(...)方法中,应该调用_sum(...),而不是sum(...)。我的坏人
杰克弹药
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.