5
$\begingroup$

I have a list $(d_1, d_2, .. d_k)$ and I want to create all sums that I get for adding only two elements for my list $(d_1+d_2, d_1+d_3,...d_{k-1}+d_k)$. The RotateLeft function gives me only some of my sums and I need all of them.

$\endgroup$
0

7 Answers 7

8
$\begingroup$
l = {a, b, c, d};
Plus @@@ Subsets[l, {2}]
(*
  {a + b, a + c, a + d, b + c, b + d, c + d}
*)

edit

Some timings

Mathematica graphics

$\endgroup$
7
$\begingroup$

Come downvote @Verde

l = {a, b, c, d}

l~Subsets~{2}~Total~{2}
$\endgroup$
6
  • $\begingroup$ (deleted comment) $\endgroup$ Commented Sep 4, 2012 at 12:41
  • 1
    $\begingroup$ This one is six times faster than the Plus @@@ solution, twice as fast as the Outer solution, and three times faster than the Table solution. $\endgroup$
    – whuber
    Commented Sep 4, 2012 at 12:50
  • $\begingroup$ And ten times slower than Total /@ Subsets[l, {2}] $\endgroup$ Commented Sep 4, 2012 at 13:39
  • 2
    $\begingroup$ @whuber l = RandomReal[1, 10^3]; {(Timing@(l~Subsets~{2}~Total~{2}))[[1]], (Timing[ Plus @@@ Subsets[l, {2}]])[[1]]} -> {2.89, 0.547} ... $\endgroup$ Commented Sep 4, 2012 at 13:43
  • $\begingroup$ @Verde You're right: that's astounding, given how similar the Total /@ and ~Total~2 constructs are!. $\endgroup$
    – whuber
    Commented Sep 4, 2012 at 14:34
4
$\begingroup$
l = {a, b, c, d};

Let's make use of pattern matching ( even though there are faster methods especially for list manipulations) :

ReplaceList[ l, {___, x_, ___, y_, ___} -> x + y]
{a + b, a + c, a + d, b + c, b + d, c + d}   

Typically, efficiency of pattern matching solutions is worse than that of functional approach, nevertheless we point out a remarkable feature of the result of ReplaceList: it is identical with other (functional) methods, e.g. (taking a longer list) we have:

ls = {a, b, c, d, e, f, g, h, i, j, k, l, , m, n, o, p, q, r, s};

ReplaceList[ls, {___, x_, ___, y_, ___} -> x + y] == 
Plus @@@ Subsets[ls, {2}] == ls~Subsets~{2}~Total~{2} 
True
$\endgroup$
3
$\begingroup$

Just to show that there's more than one way to do things in Mathematica:

test = {a, b, c, d, e};
Total /@ (Join @@ MapIndexed[Drop[#1, First[#2]] &,
          Outer[List, test, test]])
   {a + b, a + c, a + d, a + e, b + c, b + d, b + e, c + d, c + e, d + e}

Of course, Oleksandr's and Verde's suggestions are the more compact way of going about it.

$\endgroup$
3
$\begingroup$

Something like :

data = {a, b, c, d}; 

Flatten[Table[data[[i]] + data[[j]], {i, 1, Length[data] - 1}, {j, i + 1, Length[data]}],1]

(* {a + b, a + c, a + d, b + c, b + d, c + d} *)

Alternatively (plus suggestion from @Oleksandr R.) :

Total /@ Subsets[data, {2}]

And just because RotateLeft was mentioned :

Union[Flatten[Total /@ Subsets[NestList[RotateLeft[#] &, data, Length[data] - 1], {2}], 1]]
$\endgroup$
1
  • $\begingroup$ The third one seems a memory hog :) $\endgroup$ Commented Sep 4, 2012 at 14:52
2
$\begingroup$

Since somebody mentioned timings...

Module[{x = Outer[Plus, l, l]},
 Flatten[x[[#, # + 1 ;;]] & /@ Range[Length@x - 1]]]
$\endgroup$
1
$\begingroup$
Subsets[Plus @@ l, {2}]
(* or Subsets[Total@l, {2}] *)

{a + b, a + c, a + d, b + c, b + d, c + d}

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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