# Generate a list

Given the list

o = {xmin, xmax, ymin, ymax};


how can I generate the following list?

op = {{{xmin, ymin}, {xmax, ymin}}, {{xmin, ymin}, {xmin,
ymax}}, {{xmin, ymax}, {xmax, ymax}}, {{xmax, ymin}, {xmax,
ymax}}};


Thank you very much.

(Just for the sake of completeness and since it was asked, I give more details. I just wanted to generate a "Box". This was used to draw the bounding box of a rotated Ellipses, where the xmin, xmax etc are evaluated through the formulas in the article here. The replies were very helpful. I think I can generate now the 3D analog:-)!)

• How do you mean that? – Coolwater Apr 27 '15 at 13:42
• I do not see the pattern. Please describe it further. If there is no pattern, then I suppose typing the list out is the best way to generate it. – Michael E2 Apr 27 '15 at 13:49
• @MichaelE2 I see the pattern. All min and all max are excluded, but otherwise it is a pairing the x's and the y's. – rcollyer Apr 27 '15 at 14:09
• I just edited the post where I describe how it appeared the pattern. rcollyer is right. – Dimitris Apr 27 '15 at 14:20

You can get the bounding-box for an n-dimensional box like so:

bounds = {{xmin, xmax}, {ymin, ymax}};
Select[Subsets[Tuples[bounds], {2}], HammingDistance @@ # == 1 &]
(*
{{{xmin, ymin}, {xmin, ymax}}, {{xmin, ymin}, {xmax, ymin}},
{{xmin, ymax}, {xmax, ymax}}, {{xmax, ymin}, {xmax, ymax}}}
*)


If you just want to traverse each point, and not necessarily generate every edge, you can order tuples according to Gray code and then partition:

Partition[Tuples[bounds][[{1,2,4,3}]],2,1,1]
(*
{{{xmin, ymin}, {xmin, ymax}}, {{xmin, ymax}, {xmax, ymax}},
{{xmax, ymax}, {xmax, ymin}}, {{xmax, ymin}, {xmin, ymin}}}
*)


This can be drawn without lifting a pen, and while it's almost identical in 2D, it will have fewer elements in higher dimensions.

One way:-

o = {xmin, xmax, ymin, ymax};

op = {{{#1, #3}, {#2, #3}}, {{#1, #3}, {#1, #4}},
{{#1, #4}, {#2, #4}}, {{#2, #3}, {#2, #4}}} & @@ o


{{{xmin, ymin}, {xmax, ymin}}, {{xmin, ymin}, {xmin, ymax}},

{{xmin, ymax}, {xmax, ymax}}, {{xmax, ymin}, {xmax, ymax}}}

Alternatively, (output in a slightly different order).

x = DeleteCases[Tuples[{ymin, ymax}, 2], {ymax, ymin}];

y = Transpose /@ Flatten[Map[Function[z, {z, #} & /@ x],
DeleteCases[Tuples[{xmin, xmax}, 2], {xmax, xmin}]], 1] /.
{a_, a_} -> Sequence[];

DeleteCases[y, {{xmin, ymin}, {xmax, ymax}}]


{{{xmin, ymin}, {xmin, ymax}}, {{xmin, ymin}, {xmax, ymin}},

{{xmin, ymax}, {xmax, ymax}}, {{xmax, ymin}, {xmax, ymax}}}

• OK, I'll give it a +1, since it made me laugh. :D – Michael E2 Apr 27 '15 at 14:02
• I'm pretty sure this brute force method requires less time and effort than identifying the pattern. – bobthechemist Apr 27 '15 at 14:16
• @MichaelE2 - I added a more thoughtful version :-) – Chris Degnen Apr 27 '15 at 16:28
• Actually, now that I can see the pattern, I see that the Slot numbers reflect the pattern rather well. Just couldn't see it before. – Michael E2 Apr 28 '15 at 15:15

Here's a way, but it's in the wrong order:

Thread /@ (Partition[o, 2] /. {{___, #, ___} -> #} & /@ o)
(*
{{{xmin, ymin}, {xmin, ymax}}, {{xmax, ymin}, {xmax, ymax}},
{{xmin, ymin}, {xmax, ymin}}, {{xmin, ymax}, {xmax, ymax}}}
*)


If the order matters:

Thread /@ (Partition[o, 2] /. {{___, #, ___} -> #} & /@
o[[{3, 1, 4, 2}]])
(*
{{{xmin, ymin}, {xmax, ymin}}, {{xmin, ymin}, {xmin, ymax}},
{{xmin, ymax}, {xmax, ymax}}, {{xmax, ymin}, {xmax, ymax}}}
*)


P.S. A fairly easy way, given the OP has included the explicit output pattern is to use it for a replacement rule:

Replace[o, {xmin_, xmax_, ymin_, ymax_} :>
{{{xmin, ymin}, {xmax, ymin}}, {{xmin, ymin}, {xmin, ymax}},
{{xmin, ymax}, {xmax, ymax}}, {{xmax, ymin}, {xmax, ymax}}}]


ox = Partition[o, 2];

p = Table[{ox[[1, i]], ox[[2, j]]}, {i, 1, 2}, {j, 1, 2}]

{{{xmin, ymin}, {xmin, ymax}}, {{xmax, ymin}, {xmax, ymax}}}

Not sure if this is what you want.

(The original post do not have a logic pattern...)

In n-dimensions it can be done this way

dim = 2
o = Flatten[ToExpression[Table["x" <> ToString[i] <> j, {i, dim}, {j, {"min", "max"}}]]]
(*{x1min, x1max, x2min, x2max}*)

Select[Subsets[Tuples[Partition[o, 2]], {2}], Count[#[[1]] - #[[2]], 0] == dim - 1 &]
(*{{{x1min, x2min}, {x1min, x2max}}, {{x1min, x2min}, {x1max, x2min}}, {{x1min, x2max}, {x1max, x2max}}, {{x1max, x2min}, {x1max, x2max}}}*)

• Wow! Thanks a lot! – Dimitris Apr 27 '15 at 15:02
parts = Partition[o, 2]

(*
{{xmin,xmax},{ymin,ymax}}
*)

(*
{{{xmin,ymin},{xmin,ymax}},{{xmax,ymin},{xmax,ymax}}}
*)

(*
{{{xmin,ymin},{xmax,ymin}},{{xmin,ymax},{xmax,ymax}}}
*)


The above result has the Transpose relation, so, combine them

{Transpose[#], #} &@(Thread[{#, parts[[2]]}] & /@ parts[[1]])

(*
{{{{xmin,ymin},{xmax,ymin}},{{xmin,ymax},{xmax,ymax}}},{{{xmin,ymin},{xmin,ymax}},{{xmax,y
min},{xmax,ymax}}}}
*)

{Transpose[#], #} &@(Through /@ Outer @@ parts)

(*
{{{xmin[ymin],xmin[ymax]},{xmax[ymin],xmax[ymax]}},{{xmin[ymin],xmax[ymin]},{xmin[ymax],xm
ax[ymax]}}}
*)

With[{aa = Most[Subsets[Flatten[{o[[#]], Drop[o, 2]}], {2}]] & /@ Range@2},
{First@# & /@ aa, aa[[1]], Last@# & /@ aa, aa[[2]]}]