9
$\begingroup$

If I have like

{a,b}

and I want to get

 {{a+1,b},{a-1,b},{a,b+1},{a,b-1}}    

We don't care about the ordering of the list.Such as the {{a-1,b},{a+1,b},{a,b+1},{a,b-1}} also is a valid list.

This is current method

MapAt[Reverse, 
 Transpose[{Distribute[Unevaluated@Plus[{1, -1}, {a, b}], List], 
   Riffle[{b, b}, {a, a}]}], {{2}, {4}}]

{{1+a,b},{a,1+b},{-1+a,b},{a,-1+b}}

Or this

Catenate@({Tuples[{Plus[#, {1, -1}], {#2}}], 
     Tuples[{{#}, Plus[#2, {1, -1}]}]} & @@ {a, b})

{{1+a,b},{-1+a,b},{a,1+b},{a,-1+b}}

Very ugly code.Are there more beautiful solution can do this?

$\endgroup$
5
  • $\begingroup$ lis = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; {a, b} + # & /@ lis $\endgroup$
    – RunnyKine
    Apr 3, 2016 at 10:38
  • 1
    $\begingroup$ ...or {a, b} + # & /@ Join[#, -#] &[IdentityMatrix[2]]. Replace Join[] with Riffle[] if desired. $\endgroup$ Apr 3, 2016 at 10:39
  • $\begingroup$ @J.M. Yes, much nicer. $\endgroup$
    – RunnyKine
    Apr 3, 2016 at 10:43
  • $\begingroup$ Table[{a, b}, 4] + Join[#, -#] &[IdentityMatrix[2]] $\endgroup$
    – RunnyKine
    Apr 3, 2016 at 10:48
  • $\begingroup$ @RunnyKine Thanks a lots. :) $\endgroup$
    – yode
    Apr 3, 2016 at 10:50

5 Answers 5

14
$\begingroup$

The following approach will be very fast for large lists since it utilizes vectorization:

Table[{a, b}, 4] + Join[#, -#] &[IdentityMatrix[2]]
$\endgroup$
0
6
$\begingroup$

Just for fun:

Join @@ (# + {a, b} & /@ {#, -#} & /@ {{1, 0}, {0, 1}})
$\endgroup$
1
  • $\begingroup$ Thanks.Catenate[# + {a, b} & /@ {#, -#} & /@ {{1, 0}, {0, 1}}] $\endgroup$
    – yode
    Apr 3, 2016 at 10:35
4
$\begingroup$

A double Transpose might be considered "beautiful", and it certainly can be very fast too.

Transpose[Transpose[{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}] + {a, b}]
$\endgroup$
0
3
$\begingroup$

Not as fast as some of the other methods, but a TranslationTransform approach is also possible:

TranslationTransform[{a,b}][{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}]

{{-1 + a, b}, {1 + a, b}, {a, -1 + b}, {a, 1 + b}}

$\endgroup$
2
$\begingroup$
  list = {a, b};     
  Partition[Flatten@Table[ReplacePart[
          list, i -> list[[i]] + #] & /@ {1, -1}, {i, 1, 2}], 2]

  (*{{1 + a, b}, {-1 + a, b}, {a, 1 + b}, {a, -1 + b}}*)
$\endgroup$

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