[Question]
  [
You are given a multi-dimensional array of integers. Each dimension has a fixed size (so that it would be always rectangular if it is 2D). Your program should calculate the sums in each dimension and append the sums as the new last items in that dimension.
Assume the input and output arrays are A and B, and the size of dimension *i* of A is ni. B would have the same number of dimensions as A and the size of dimension *i* would be ni+1. Bj1,j2,...,jm is the sum of Ak1,k2,...,km where:
* ki = ji if ji <= ni
* 0 < ki <= ni if ji = ni+1
For the input:
```
[[1 2 3]
 [4 5 6]]
```
Your program (or function) should output:
```
[[1 2 3 6]
 [4 5 6 15]
 [5 7 9 21]]
```
The input contains only the array. The total number of dimensions and the size of each dimension are **not** given in the input. (But you can get them from the array by your own code.) You can use any convenient list formats in your language, as long as it doesn't specify the number of dimensions or dimension sizes directly.
The input has at least 1 dimension, and has at least 1 item in the array.
This is code-golf. Shortest code wins.
## Test cases
```
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]]]]
```
  
[Answer]
# Mathematica, ~~32~~ 20 bytes
```
#/.List->({##,+##}&)&
```
### Example:
```
In[1]:= #/.List->({##,+##}&)&[{{1, 2, 3}, {4, 5, 6}}]
Out[1]= {{1, 2, 3, 6}, {4, 5, 6, 15}, {5, 7, 9, 21}}
```
### Explanation:
The full form of `{{1, 2, 3}, {4, 5, 6}}` is `List[List[1, 2, 3], List[4, 5, 6]]`. Then replace all the `List`s in the expression with the function `({##,+##}&)`.
[Answer]
## Python 2, 95 bytes
```
from numpy import*
a=copy(input())
for d in r_[:a.ndim]:a=r_[`d`,a,sum(a,d,keepdims=1)]
print a
```
This iterates over each dimension, concatenating its sums using NumPy.
I stumbled across NumPy's [`r_`](http://docs.scipy.org/doc/numpy/reference/generated/numpy.r_.html#numpy-r), which is pretty awesome for golfing. `r_[:n]` is shorter than `range(n)` and much more powerful (e.g. `r_[:4, 7, 8, 10:100:10]`). It can also do other things like concatenation along an arbitrary axis.
Example usage:
```
$ python sum.py
[[1, 2, 3], [4, 5, 6]]
[[ 1  2  3  6]
 [ 4  5  6 15]
 [ 5  7  9 21]]
```
[Answer]
# J, 14 bytes
```
#@$(0|:],+/^:)
```
Usage: 
```
   ]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
```
The function is equivalent to the following `(0|:],+/)^:(#@$)` but uses a user-defined adverb to save parens.
Explanation for the latter code from right to left:
* `^:(#@$)`repeat `^:` for the number `#` of dimensions `$`:
	+ `],+/` concatenate `,` to the argument `]` with the sum of it on the last dimension `+/`
	+ `0|:` rotate dimensions `|:` by putting the first one `0` to the end of the dimension-list
* After doing the above procedure we get back the original input with sums on all dimensions.
*For my older solution check revision history.*
[Try it online here.](http://tryj.tk/)
[Answer]
# APL, ~~16~~ 15 bytes
```
{×≡⍵:∇¨⍵,+/⍵⋄⍵}
```
*Thanks to @user23013 for golfing off 3 bytes and figuring out the proper input format.*
Verify the test cases online with [TryAPL](http://tryapl.org/?a=sum%u2190%7B%D7%u2261%u2375%3A%u2207%A8%u2375%2C+/%u2375%u22C4%u2375%7D%20%u22C4%20sum%205%202%203%20%u22C4%20sum%20%281%202%203%29%284%205%206%29%20%u22C4%20sum%20%2C%u2282%28%2C1%29%28%2C1%29%28%2C1%29%28%2C0%29%20%u22C4%20sum%20%u2282%u2282%u2282%2C%AF1&run).
### Idea
The general idea is the same as in my CJam submission, for which APL allows a much shorter implementation. It consists of only two steps:
1. Sum the array across its outmost dimension.
2. Repeat step 1 for each subarray.
### Code
```
{             } ⍝ 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 ⍵.
```
[Answer]
# [Pip](http://github.com/dloscutoff/pip), ~~18~~ 15 bytes
```
{a-a?fMaAE$+aa}
```
This is an anonymous function, which takes the array as an argument and returns the result. Sample invocation, using the `-p` flag to obtain readable output:
```
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]]
```
The idea is basically the same as [Dennis's APL](https://codegolf.stackexchange.com/a/50654/16766), though independently derived. More specifically:
```
{             }  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
```
This method works because `+` (along with many other operators) functions item-wise on lists in Pip--a feature inspired by array-programming languages like APL. So when you `$+` a list like `[[1 2 3] [4 5 6]]`, the result is `[5 7 9]` as desired. Also used in the list-or-scalar test: `[1 2 3] - [1 2 3]` gives `[0 0 0]`, which is truthy (as are all lists except the empty list).
Previous 18-byte version:
```
{Ja=a?a(fMaAE$+a)}
```
Changes:
1. Saved a byte on the scalar-or-list test--previous method was to join the argument (on empty string) and test whether equal to its un-joined self (works because `[1 2 3] != 123`);
2. Eliminated the parentheses. They're necessary in the original because `M` is lower precedence than `?` (though I'm probably going to change that, especially now): without them, the code would parse as `(Ja=a?af)M(aAE$+a)`, leading to bizarre error messages. However, the middle argument of a ternary operator can be *any* expression of whatever precedence, no parentheses needed. So by making the list the truthy case, I can save those two bytes.
[Answer]
# APL (25)
```
{N⊣{N,[⍵]←+/[⍵]N}¨⍳⍴⍴N←⍵}
```
APL's arrays have dimensions built-in, so this is a function that takes an *n*-dimensional array and then sums along each dimension.
```
      {N⊣{N,[⍵]←+/[⍵]N}¨⍳⍴⍴N←⍵} ↑(1 2 3)(4 5 6)
1 2 3  6
4 5 6 15
5 7 9 21
```
Explanation:
* `N←⍵`: store the array in `N`.
* `⍴⍴N`: get the amount of dimensions `N` has. (`⍴` gives the dimensions, i.e. `⍴↑(1 2 3)(4 5 6)` gives `2 3`, so `⍴⍴` gives the dimensions of the dimensions.)
* `{`...`}¨⍳`: for each number from 1 to `⍴⍴N`:
	+ `+/[⍵]N`: sum `N` along dimension `⍵`
	+ `N,[⍵]←`: join the result to `N` in that dimension
* `N`: finally, return `N`.
[Answer]
# CJam, 36 bytes
```
{_`{'[<}#:D{_":"D'.e]'++~a+{S}%}&}:S
```
This is a recursive named function that pops an array from the stack and leaves one in return.
Try the test cases in the [CJam interpreter](http://cjam.aditsu.net/#code=%7B_%60%7B'%5B%3C%7D%23%3AD%7B_%22%3A%22D'.e%5D'%2B%2B~a%2B%7BS%7D%25%7D%26%7D%3AS%20e%23%20Define%20S.%0A%0A%20qN%2F%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20e%23%20Read%20from%20STDIN%20and%20split%20at%20linefeeds.%0A%7B~Sp%7D%2F%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20e%23%20Evaluate%20each%20line%2C%20execute%20S%20and%20print.%0A%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20e%23%20Clear%20the%20stack.&input=%5B5%202%203%5D%0A%5B%5B1%202%203%5D%20%5B4%205%206%5D%5D%0A%5B%5B%5B1%5D%20%5B1%5D%20%5B1%5D%20%5B0%5D%5D%5D%0A%5B%5B%5B%5B-1%5D%5D%5D%5D).
### Idea
Sadly, CJam does not have some automagical operator that allows to add arbitrarily nested arrays, so we have to implement it ourselves. Luckily, it does that two infix operators, `:` (reduce) and `.` (vectorize), that will prove helpful for this task.
Step one is calculating the number of dimensions. This is easy: Convert the array into its string representation and count the number of leading **[**'s.
Now, to reduce an array of one dimension, you usually just execute `:+`:
```
[1 2] :+ e# Pushes 3.
```
For an array of two dimensions, `+` would perform concatenation instead of addition, so we have to vectorize it:
```
[[1 2][3 4]] :.+ Pushes [4 6].
```
Now, for an array of three dimensions, `.+` would operate on arrays of two dimensions and perform, once again, concatenation. This time, we have to vectorize `.+`:
```
[[[1 2][3 4]][[5 6][7 8]]] :..+ e# Pushes [[[6 8] [10 12]]].
```
For the general case, an array of dimension **D**, we have to chain one `:`, **D - 1** `.`'s and one `+`.
Of course, this only sums the array only across its outmost dimension. We can solve this by defining a function **S** that computes the dimension (and does nothing if it's zero), performs the sum as indicated above and, finally, applies itself to the array's elements.
### Code
```
{                                }: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.
```
[Answer]
## Ruby (~~181~~ ~~139~~ ~~119~~ 108 bytes)
```
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
```
Assumes input is passed as JSON.
[Answer]
# Java, 669 bytes
not gonna lie, I'm quite proud of myself for this one :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;}}
```
expanded with testing:
```
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();
    }
}
```
running the expanded testing version prints this:
```
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 ] ] ] 
```
]