Column-wise Sum

30

1

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]

flawr

Posted 2016-12-17T22:54:14.503

Reputation: 40 560

Will the arrays only contain integers? – ETHproductions – 2016-12-19T21:18:39.150

I did not think about that so far but I think you can assume that. Is there anything speaking against that? – flawr – 2016-12-19T21:40:34.493

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). – ETHproductions – 2016-12-19T21:43:51.483

Well then I think that this assumption is perfectly acceptable. It also doesn't change the challenge itself. – flawr – 2016-12-19T21:53:54.687

Answers

19

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.

Dennis

Posted 2016-12-17T22:54:14.503

Reputation: 196 637

1Huh, 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? – None – 2016-12-17T23:03:08.037

1For a 2D array, yes. / does not vectorize; it simply applies the corresponding dyad to all elements of its argument. – Dennis – 2016-12-17T23:12:14.400

11

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!

Dennis

Posted 2016-12-17T22:54:14.503

Reputation: 196 637

9

Perl 6, 23 bytes

{roundrobin(|$_)».sum}

smls

Posted 2016-12-17T22:54:14.503

Reputation: 4 352

9

Mathematica, 15 bytes

Total@*PadRight

alephalpha

Posted 2016-12-17T22:54:14.503

Reputation: 23 988

8

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]

Laikoni

Posted 2016-12-17T22:54:14.503

Reputation: 23 676

Good to know the libraries, I'm always afraid of the import as it already eats up so many bytes :D – flawr – 2016-12-18T09:50:44.167

8

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

Luis Mendo

Posted 2016-12-17T22:54:14.503

Reputation: 87 464

7

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

Luis Mendo

Posted 2016-12-17T22:54:14.503

Reputation: 87 464

Very clever to use cells=) – flawr – 2016-12-18T09:53:22.453

4

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]

Arnauld

Posted 2016-12-17T22:54:14.503

Reputation: 111 334

What was wrong with reduce? a=>a.reduce((l,r)=>r.map((e,i)=>e+(l[i]||0))) is only 45 bytes. – Neil – 2016-12-18T17:17:34.760

@Neil Wouldn't that limit the size of the final result to the size of the last processed array? – Arnauld – 2016-12-18T17:28:39.537

Ah, the test cases failed to catch my error, thanks! – Neil – 2016-12-18T17:43:48.313

3

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

flawr

Posted 2016-12-17T22:54:14.503

Reputation: 40 560

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>[]]. – Laikoni – 2016-12-18T02:41:36.073

Wow thank you very much! I keep forgetting about the possibility of pattern matching in [h|h:_<-l]! – flawr – 2016-12-18T09:45:52.883

One byte can be saved in the recursive call: f[t:u|_:t:u<-l]. – nimi – 2016-12-18T10:20:21.893

3

Wonder, 11 bytes

@->#sum '#0

Transpose and map with sum function. Usage:

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

Mama Fun Roll

Posted 2016-12-17T22:54:14.503

Reputation: 7 234

3

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;
}

Karl Napf

Posted 2016-12-17T22:54:14.503

Reputation: 4 131

3

Pyth - 4 bytes

sM.T

Try it online here.

Maltysen

Posted 2016-12-17T22:54:14.503

Reputation: 25 023

2

Dyalog APL, 3 bytes

+⌿↑

+⌿ sum column-wise

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

TryAPL online!

Adám

Posted 2016-12-17T22:54:14.503

Reputation: 37 779

2How on earth is this 10 bytes? – Zacharý – 2016-12-19T00:52:29.767

3@ZacharyT That's what happens when using a template at 12:30 AM. – Adám – 2016-12-19T01:26:16.293

2

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

Conor O'Brien

Posted 2016-12-17T22:54:14.503

Reputation: 36 228

1

Pyke, 4 bytes

.,ms

Try it here!

Blue

Posted 2016-12-17T22:54:14.503

Reputation: 26 661

1

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.

Jack Ammo

Posted 2016-12-17T22:54:14.503

Reputation: 430

1

Octave, 69 bytes

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

rahnema1

Posted 2016-12-17T22:54:14.503

Reputation: 5 435

1

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 !

Frédéric

Posted 2016-12-17T22:54:14.503

Reputation: 2 059

colSums(a,na.rm=T) saves a few bytes. – JAD – 2016-12-18T12:42:19.140

and you can even turn na.rm=T into n=T. – JAD – 2016-12-18T12:48:15.463

1

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.

Titus

Posted 2016-12-17T22:54:14.503

Reputation: 13 814

0

Clojure, 70 bytes

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

A basic nested loop.

NikoNyrh

Posted 2016-12-17T22:54:14.503

Reputation: 2 361

0

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].

ETHproductions

Posted 2016-12-17T22:54:14.503

Reputation: 47 880