I am very new to Mathematica. I have code written using for loops. I want to rewrite it using Map
/Thread
but I am not sure how to do it.
My code takes the set A
, say
A = {{1, 2, 3, 1, 2, 3}, {1, 1, 2, 2, 3, 3}}
Then it insert a arbitrary character(say $a$) to every possible positions of given element in the set A
. So we get
{{a, 1, 2, 3, 1, 2, 3}, {1, a, 2, 3, 1, 2, 3}, ...,
{a, 1, 1, 2, 2, 3, 3}, ..., {1, 1, 2, 2, 3, 3, a}}
Then it inserts the same character again into resulting elements in following manner
{{a, a, 1, 2, 3, 1, 2, 3}, {a, 1, a, 2, 3, 1, 2, 3},
{a, 1, 2, a, 3, 1, 2, 3}, ...., {1, 1 , 2, 2, 3, 3, a}}
This question come from Knot Theory-Chord Diagram
My program using for loops is follows.
A = {{1, 2, 3, 1, 2, 3}, {1, 1, 2, 2, 3, 3}};
kk = Length[A[[1]]]/2 + 1;
B = {};
For[m = 1, m < Length[A] + 1, m++,
Diag1 = A[[m]];
For[j = 1, j < (2*kk), j++,
Diag2 = Insert[Diag1, "a", j];
For[i = 1 + j, i < (2*kk) + 1, i++,
Diag3 = Insert[Diag2, "a", i];
B = AppendTo[B, Diag3];
];
];
];
This is what I tried to do with element 2.
f[x_] := Insert[A[[2]], "a", x];
B = Map[f, Range[7]]];
But I don't know how to put variable A[[i]]
instead of A[[2]]
and also how to insert other end of $a$ to this result using map.
Any comment really appreciated.
Answer
There is a rule/replacement based method using ReplaceList
and BlankNullSequence
that I think is elegant and easy to understand.
ReplaceList[{1, 2, 3}, {a___, b___} :> {a, x, b}]
{{x, 1, 2, 3}, {1, x, 2, 3}, {1, 2, x, 3}, {1, 2, 3, x}}
ReplaceList[{1, 2, 3}, {a___, b___, c___} :> {a, x, b, x, c}]
{{x, x, 1, 2, 3}, {x, 1, x, 2, 3}, {x, 1, 2, x, 3}, {x, 1, 2, 3, x}, {1, x, x, 2, 3},
{1, x, 2, x, 3}, {1, x, 2, 3, x}, {1, 2, x, x, 3}, {1, 2, x, 3, x}, {1, 2, 3, x, x}}
The only difficulty is extending this to an arbitrary number of insertions. For that we need meta-programming, that is code that generates code:
sprinkle[v_List, x_, n_Integer?Positive] :=
Table[Unique["a", Temporary], {n + 1}] /. syms_ :>
ReplaceList[v, Pattern[#, ___] & /@ syms -> Riffle[syms, x]]
Now:
sprinkle[{1, 2, 3}, x, 4]
{{x, x, x, x, 1, 2, 3}, {x, x, x, 1, x, 2, 3}, {x, x, x, 1, 2, x, 3}, ... }
Your original example may be had with:
A = {{1, 2, 3, 1, 2, 3}, {1, 1, 2, 2, 3, 3}};
Join @@ (sprinkle[#, a, 2] & /@ A)
You can leave off the Join @@
if you want two sets of sublists; I could not tell form your question if that was desired.
Note: using a capital letter to start a user Symbol name is often a bad idea as these may conflict with internal functions – I preserved your original name for clarity alone.
Comments
Post a Comment