5

Given {a, b, c, ...} with $n$ elements generate a list with $2^n$ elements.

For example, if the list were {a, b, c}, then the output should be

{{a, b, c}, {a, b, -c}, {a, -b, c}, ..., {-a, -b, -c}}

If possible, I want to use buit-in functions so that the task can be performed without looping. My own solutions using Subsets[{-1,-1,...} are very messy.

m_goldberg
  • 107,779
  • 16
  • 103
  • 257

4 Answers4

8

I too would use Tuples but a bit differently. I propose:

f2[a_List] := Tuples[ {a, -a}\[Transpose] ]

Now:

f2[{a, b, c}]
{{a,b,c}, {a,b,-c}, {a,-b,c}, {a,-b,-c}, {-a,b,c}, {-a,b,-c}, {-a,-b,c}, {-a,-b,-c}}

This is both shorter and an order of magnitude faster than rhermans's formulation:

First @ Timing @ Do[# @ Range @ 18, {100}] & /@ {f, f2}
{4.368028, 0.358802}
Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
6

Solution

f[list_] := list # & /@ Tuples[{1, -1}, Length[list]]

Example

f[{a, b, c, d}]
{{a, b, c, d}, {a, b, c, -d}, {a, b, -c, d}, {a, b, -c, -d}, {a, -b, c, d}, {a, -b, c, -d}, {a, -b, -c, d}, {a, -b, -c, -d}, {-a, b, c, d}, {-a, b, c, -d}, {-a, b, -c, d}, {-a, b, -c, -d}, {-a, -b, c, d}, {-a, -b, c, -d}, {-a, -b, -c, d}, {-a, -b, -c, -d}}

Explanation

Tuples generates a list of all possible n-tuples of elements from list.

Tuples[{-1, 1}, 3]
{{-1, -1, -1}, {-1, -1, 1}, {-1, 1, -1}, {-1, 1, 1}, {1, -1, -1}, {1, -1, 1}, {1, 1, -1}, {1, 1, 1}}

Then the hieroglyphics part, list # & /@, multiplies the list to each sublist of the combinations of 1s and -1s, using Map (/@) and Function (# &)

rhermans
  • 36,518
  • 4
  • 57
  • 149
5

Another method:

plusMinus[symlist_List] := 
 With[{n = Length[symlist]}, 
  Map[symlist*# &, 
   Table[IntegerDigits[j, 2, n], {j, 2^n - 1}] /. 0 -> -1]]

plusMinus[{a, b, c, d}]

(*  Out[11]= {{-a, -b, -c, d}, {-a, -b, c, -d}, {-a, -b, c, d}, {-a, 
  b, -c, -d}, {-a, b, -c, d}, {-a, b, c, -d}, {-a, b, c, 
  d}, {a, -b, -c, -d}, {a, -b, -c, d}, {a, -b, c, -d}, {a, -b, c, 
  d}, {a, b, -c, -d}, {a, b, -c, d}, {a, b, c, -d}, {a, b, c, d}} *)

If you do not need to maintain ordering there is also this.

plusMinus2[symlist_List] := 
 Map[Join[-Complement[symlist, #], #] &, Subsets[symlist]]

plusMinus2[{a, b, c, d}]

(* Out[19]= {{-a, -b, -c, -d}, {-b, -c, -d, a}, {-a, -c, -d, 
  b}, {-a, -b, -d, c}, {-a, -b, -c, d}, {-c, -d, a, b}, {-b, -d, a, 
  c}, {-b, -c, a, d}, {-a, -d, b, c}, {-a, -c, b, d}, {-a, -b, c, 
  d}, {-d, a, b, c}, {-c, a, b, d}, {-b, a, c, d}, {-a, b, c, d}, {a, 
  b, c, d}} *)
Daniel Lichtblau
  • 58,970
  • 2
  • 101
  • 199
3

For symbolic input data BooleanMinterms and BooleanMaxterms may be of use:

g = Block[{And = List, Not = (-# &)}, Table[BooleanMinterms[{i-1}, {##}], {i, 2^Length[{##}]}]] &;

g[a, b, c, d]
(* {{-a,-b,-c,-d},{-a,-b,-c,d},{-a,-b,c,-d},{-a,-b,c,d},{-a,b,-c,-d},{-a,b,-c,d},
    {-a,b,c,-d},{-a,b,c,d},{a,-b,-c,-d},{a,-b,-c,d},{a,-b,c,-d},{a,-b,c,d},
    {a,b,-c,-d},{a,b,-c,d},{a,b,c,-d},{a,b,c,d}} *)

BooelanMaxTerms can be used similarly with || playing the role of && above.

kglr
  • 394,356
  • 18
  • 477
  • 896