30
\$\begingroup\$

Given a nonempty list of nonempty rows of numbers, compute the column wise sum, which is another list that has the length of the longest input row. The first entry of the output list is the sum of all the first entires of the input rows, the second one is the sum of all the second elements (if available) etc. I think following example will explain it way better:

Input:      {[1,2,3,4],[1],[5,2,3],[6,1]}
Computation: [1,2,3,4]
              + . . .
             [1]. . .
              + + + .
             [5,2,3].
              + + . .
             [6,1]. .
              = = = =
    Output: [13,5,6,4]

Test Cases

{[0]}                         -> 0
{[1],[1,1,1,1]}               -> [2,1,1,1]
{[1],[1,2],[1,2,3],[1,2,3,4]} -> [4,6,6,4]
{[1,6,2,-6],[-1,2,3,5]}       -> [0,8,5,-1]
\$\endgroup\$
  • \$\begingroup\$ Will the arrays only contain integers? \$\endgroup\$ – ETHproductions Dec 19 '16 at 21:18
  • \$\begingroup\$ I did not think about that so far but I think you can assume that. Is there anything speaking against that? \$\endgroup\$ – flawr Dec 19 '16 at 21:40
  • \$\begingroup\$ I don't think so. All of your test cases use only integers, and I'm fairly certain it won't invalidate any existing answers (and may even save bytes for some answers). \$\endgroup\$ – ETHproductions Dec 19 '16 at 21:43
  • \$\begingroup\$ Well then I think that this assumption is perfectly acceptable. It also doesn't change the challenge itself. \$\endgroup\$ – flawr Dec 19 '16 at 21:53

21 Answers 21

19
\$\begingroup\$

Jelly, 1 byte

S

Try it online! or verify all test cases.

How it works

The sum atom S is a shorthand for +/, which performs reduction by addition.

The quick / reduces along the outmost dimension, so it calls its link for the elements of the input. Here, the elements are the rows.

The addition atom + vectorizes, so adding two row vectors perform element-by-element addition. When the arguments have different lengths, the elements of the longer argument that have no counterpart in the shorter one are left unaltered.

All in all, with an irregular matrix as argument, S computes the column-wise sum, skipping missing entries in the shorter rows.

\$\endgroup\$
  • 1
    \$\begingroup\$ Huh, I'd have expected that to be row-wise sum, given the way autovectorisation normally works in Jelly. I take it row-wise sum would be S€, then? \$\endgroup\$ – user62131 Dec 17 '16 at 23:03
  • 1
    \$\begingroup\$ For a 2D array, yes. / does not vectorize; it simply applies the corresponding dyad to all elements of its argument. \$\endgroup\$ – Dennis Dec 17 '16 at 23:12
11
\$\begingroup\$

Python 2, 47 45 bytes

lambda x:map(lambda*y:sum(filter(None,y)),*x)

Thanks to @vaultah for golfing off 2 bytes!

Try it online!

\$\endgroup\$
9
\$\begingroup\$

Perl 6, 23 bytes

{roundrobin(|$_)».sum}
\$\endgroup\$
9
\$\begingroup\$

Mathematica, 15 bytes

Total@*PadRight
\$\endgroup\$
8
\$\begingroup\$

Haskell, 34 bytes

import Data.List
map sum.transpose

Try it online! Usage:

Prelude Data.List> map sum.transpose $ [[1,2,3,4],[1],[5,2,3],[6,1]]
[13,5,6,4]
\$\endgroup\$
  • \$\begingroup\$ Good to know the libraries, I'm always afraid of the import as it already eats up so many bytes :D \$\endgroup\$ – flawr Dec 18 '16 at 9:50
8
\$\begingroup\$

CJam, 7 5 bytes

2 bytes off thanks to Dennis!

{:.+}

This defines an anonymous block that takes a list of lists, such as [[1 2 3 4] [1] [5 2 3] [6 1]], and replaces it by a list, [13 5 6 4].

Try it online! Or verify all test cases.

Explanation

{   }   e# Define block
 :      e# Fold over the following dyadic function
  .+    e# Vectorized addition
\$\endgroup\$
7
\$\begingroup\$

MATL, 3 bytes

oXs

(MATL doesn't know that the plural of "ox" is "oxen"...)

Input is a cell array of numeric row vectors, in the same format as in the challenge text:

{[1,2,3,4],[1],[5,2,3],[6,1]}

Try it online! Or verify all test cases.

     % Implicit input
o    % Convert cell array to a matrix, right-padding with zeros each row
Xs   % Sum of each column
     % Implicit display
\$\endgroup\$
  • \$\begingroup\$ Very clever to use cells=) \$\endgroup\$ – flawr Dec 18 '16 at 9:53
4
\$\begingroup\$

JavaScript (ES6), 51 48 bytes

Saved 3 bytes, thanks to ETHproductions

a=>a.map(b=>b.map((v,i)=>r[i]=~~r[i]+v),r=[])&&r

Test cases

let f =

a=>a.map(b=>b.map((v,i)=>r[i]=~~r[i]+v),r=[])&&r

console.log(f([[1,2,3,4],[1],[5,2,3],[6,1]])); // -> [13,5,6,4]
console.log(f([[0]]));                         // -> [0]
console.log(f([[1],[1,1,1,1]]));               // -> [2,1,1,1]
console.log(f([[1],[1,2],[1,2,3],[1,2,3,4]])); // -> [4,6,6,4]
console.log(f([[1,6,2,-6],[-1,2,3,5]]));       // -> [0,8,5,-1]

\$\endgroup\$
  • \$\begingroup\$ What was wrong with reduce? a=>a.reduce((l,r)=>r.map((e,i)=>e+(l[i]||0))) is only 45 bytes. \$\endgroup\$ – Neil Dec 18 '16 at 17:17
  • \$\begingroup\$ @Neil Wouldn't that limit the size of the final result to the size of the last processed array? \$\endgroup\$ – Arnauld Dec 18 '16 at 17:28
  • \$\begingroup\$ Ah, the test cases failed to catch my error, thanks! \$\endgroup\$ – Neil Dec 18 '16 at 17:43
3
\$\begingroup\$

Wonder, 11 bytes

@->#sum '#0

Transpose and map with sum function. Usage:

(@->#sum '#0)[[1 2 3 4];[1];[5 2 3];[6 1]]
\$\endgroup\$
3
\$\begingroup\$

C++14, 130 bytes

As unnamed generic lambda:

[](auto C,auto&r){r.clear();int i=0,b=1;while(b--){r.push_back(0);for(auto c:C)r.back()+=i<c.size()?c[b=1,i]:0;++i;}r.pop_back();}

Requires C to be like vector<vector<int>> and return value r to be like vector<int> (should be okay according to meta).

Ungolfed & usage:

#include<vector>
#include<iostream>

auto f=
[](auto C, auto&r){
 r.clear();         //clearing r just to be sure
 int i=0,b=1;       //i is the position in the row, b is a boolean
 while(b--){        //while something was added
  r.push_back(0);   //add zero
  for(auto c:C)     //for each container
   r.back() += i<c.size() ?   //add to the last element 
    c[b=1,i] : 0;             //set b and get the element or zero 
  ++i;              
 }
 r.pop_back();      //remove last unnecessary zero
}
;

using namespace std;

int main(){
 vector<vector<int> > C = { {1,2,3,4}, {1}, {5,2,3}, {6,1} };
 vector<int> r; 
 f(C,r);
 for (int i: r)
  cout << i << ", ";
 cout << endl;
}
\$\endgroup\$
3
\$\begingroup\$

Pyth - 4 bytes

sM.T

Try it online here.

\$\endgroup\$
3
\$\begingroup\$

Haskell, 61 41 40 bytes

Thanks @Laikoni for -20 bytes, @nimi for -1 byte!

f[]=[]
f l=sum[h|h:_<-l]:f[t:u|_:t:u<-l]

Explanation: It is just a recursive summation of the first elements of the list, also dealing with discarding empty lists in every intermediate step:

    sum[h|h:_<-l]                    -- sums up all the first elemetns of the list
                    [t:u|_:t:u<-l]   -- removes the first element of all the list, and removes empty lists
                   f                 -- applies f to the remaining list
                 :                   -- prepends the sum to the rest
\$\endgroup\$
  • \$\begingroup\$ Using list comprehensions saves quite some bytes: You can replace (sum$sum.(take 1)<$>l) with sum[h|h:_<-l] and (f$filter(/=[])$drop 1<$>l) with f[t|_:t<-l,t>[]]. \$\endgroup\$ – Laikoni Dec 18 '16 at 2:41
  • \$\begingroup\$ Wow thank you very much! I keep forgetting about the possibility of pattern matching in [h|h:_<-l]! \$\endgroup\$ – flawr Dec 18 '16 at 9:45
  • \$\begingroup\$ One byte can be saved in the recursive call: f[t:u|_:t:u<-l]. \$\endgroup\$ – nimi Dec 18 '16 at 10:20
2
\$\begingroup\$

J, 5 bytes

+/@:>

Takes input as a boxed list of lists.

Test cases

   1 ; 1 1 1 1
+-+-------+
|1|1 1 1 1|
+-+-------+
   (+/@:>) 1 ; 1 1 1 1
2 1 1 1
   1 ; 1 2 ; 1 2 3 ; 1 2 3 4
+-+---+-----+-------+
|1|1 2|1 2 3|1 2 3 4|
+-+---+-----+-------+
   (+/@:>) 1 ; 1 2 ; 1 2 3 ; 1 2 3 4
4 6 6 4
\$\endgroup\$
2
\$\begingroup\$

Dyalog APL, 3 bytes

+⌿↑

+⌿ sum column-wise

the mixed (list of list, stacked into matrix, padding with zeros) argument

TryAPL online!

\$\endgroup\$
  • 2
    \$\begingroup\$ How on earth is this 10 bytes? \$\endgroup\$ – Zacharý Dec 19 '16 at 0:52
  • 3
    \$\begingroup\$ @ZacharyT That's what happens when using a template at 12:30 AM. \$\endgroup\$ – Adám Dec 19 '16 at 1:26
1
\$\begingroup\$

Pyke, 4 bytes

.,ms

Try it here!

\$\endgroup\$
1
\$\begingroup\$

Java 8, 124 bytes

this is a lambda expression for a Function< int[ ][ ], int[ ] >

i->{int L=0,t,r[];for(int[]a:i)L=(t=a.length)>L?t:L;r=new int[L];for(;0>L--;)for(int[]a:i)r[L]+=a.length>L?a[L]:0;return r;}

it takes the largest array length from the input, creates a new array of that size, and then writes the sums of each column to the array.

\$\endgroup\$
1
\$\begingroup\$

Octave, 69 bytes

@(a){g=1:max(s=cellfun(@numel,a))<=s';f=g'+0;f(g')=[a{:}];sum(f')}{4}
\$\endgroup\$
1
\$\begingroup\$

R, 105 97 bytes

a=c();l=length;for(i in 1:l(w)){length(w[[i]])=max(sapply(w,l));a=rbind(a,w[[i]])};colSums(a,n=T)

This takes in input a list object called w in the form :

w=list(c(1,2,3,4),c(1),c(1,2))

It outputs the column-wise sum : [1] 3 4 3 4

This solution is quite long to me. R has the particularity to recycle when you try to bind vectors of different length. For example :

a=c(1,2,3,4)
b=c(1,2)

cbind(a,b)

     a b
[1,] 1 1
[2,] 2 2
[3,] 3 1
[4,] 4 2

b is re-used once to fit, which is why I begin with a list.

The program adjusts the length of all the elements of the list as the one of the longest, binds the elements and computs the column-wise sum. The length adjusting produces NA's, that are ignored by the sum.

-8 bytes thanks to @Jarko Dubbeldam !

\$\endgroup\$
  • \$\begingroup\$ colSums(a,na.rm=T) saves a few bytes. \$\endgroup\$ – JAD Dec 18 '16 at 12:42
  • \$\begingroup\$ and you can even turn na.rm=T into n=T. \$\endgroup\$ – JAD Dec 18 '16 at 12:48
1
\$\begingroup\$

PHP, 63 bytes

<?foreach($_GETas$a)foreach($a as$i=>$x)$r[$i]+=$x;print_r($r);

call in browser with GET parameters as list of inputs.

Example:
script.php?a[]=1&a[]=2&a[]=3&a[]=4&b[]=1&c[]=5&c[]=2&c[]=3&d[]=6&d[]=1
(Array names are ignored, so you can name them any way you want.)

Try this function for testing:

function s($a){foreach($a as$b)foreach($b as$i=>$x)$r[$i]+=$x;return$r;}

or use http_build_query($array,a) to convert a given array of arrays to GET parameters.

\$\endgroup\$
0
\$\begingroup\$

Clojure, 70 bytes

#(for[i(range(apply max(map count %)))](apply +(for[v %](get v i 0))))

A basic nested loop.

\$\endgroup\$
0
\$\begingroup\$

Japt, 5 bytes

Uz mx

Test it online!

U is the input array, and z on arrays rotates the array clockwise by 90 degrees. Therefore,

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

becomes

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

(Spacing added only for display purposes.)

mx then maps by summation (x), which gives the desired result: [13,5,6,4].

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.