# String permutation

I have a string "abcd". Is there any way in Mathematica such that when I apply some exchange operator $$P^{ab}$$ it gives me string "bacd"?

Edit:

So, I would like to have something such that I can apply multiple permutations eventually. For example:

$$P^{xy}P^{xa}P^{ya}$$"xya"="ayx"

$$P^{ya}P^{xa}P^{xy}$$"xya"="ayx"

and so on.

I am still confused as to how to implement these because the answers sort of do S<>S to change specific ones. Is there a way I can implement these?

• It is much easier to manipulate lists, such as {1,2,3,4}. You can convert them to strings as desired. Sep 8, 2021 at 18:36
• What do you want $P^{ya}$"yxa" to return? Should it be "yxa" or "axy"? Sep 15, 2021 at 18:13
• @CarlWoll I would $P^{ya}$"yxa" to return "axy". For this purpose, I would like to not differentiate between $P^{ya}$ and the inverse $P^{ay}$. Sep 16, 2021 at 0:25
• My answer returns "axy", while the accepted answer returns "yxa". This is why I asked. Sep 16, 2021 at 2:55
• @CarlWoll it was indeed a mistake; I wanted to accept your solution but accidentally did a different one. I really liked your answer. It is amazingly done. Sep 17, 2021 at 11:23

You can use StringReplace:

StringReplace[StartOfString~~s1_~~s2_ :> s2 <> s1] @ "abcd"


"bacd"

Update

For your updated question you could do:

p[s_String /; StringLength[s]==2] := With[{x=StringPart[s,1],y=StringPart[s,2]},
StringReplace[{x->y,y->x}]
]


Examples:

p["xy"] @ p["xa"] @ p["ya"] @ "xya"
p["ya"] @ p["xa"] @ p["xy"] @ "xya"


"ayx"

"ayx"

• Thank you so much. This is beautiful. Sep 15, 2021 at 18:09

Update: For the updated version of OP:

strngRvrs = RightComposition @@ (StringReplace[# -> StringReverse@#] & /@ {##}) &;


Examples:

strngRvrs["xy"]@"xya"

"yxa"

strngRvrs["xy", "xa", "ya"]@"xya"

"ayx"

strngRvrs["ya", "xa", "xy"]@"xya"

"ayx"

strngRvrs["cd", "cef", "bd"]@"abcdefgh"

"adbfecgh"


1. You can combine StringJoin + StringTakeDrop + StringReverse as follows:

ClearAll[stringShuffle1]
stringShuffle1 = StringJoin[StringReverse @ #, #2] & @@ StringTakeDrop @ ## &;

stringShuffle1["abcd", 2]

"bacd"

stringShuffle1["abcd", 3]

"cbad"

stringShuffle1["abcdefghij", 5]

"edcbafghij"


2. StringJoin + Characters + Permute

ClearAll[stringShuffle2]
stringShuffle2 = StringJoin @ Permute[Characters @ #, Reverse @ Range @ #2] &;

stringShuffle2["abcd", 2]

"bacd"

stringShuffle2["abcdefghij", 2]

"bacdefghij"

stringShuffle2["abcdefghij", 4]

"dcbaefghij"


3. StringJoin + Characters + PermutationList

ClearAll[stringShuffle3]
stringShuffle3 = StringJoin @
Characters[#][[PermutationList[Reverse@Range@#2, StringLength@#]]] &;

stringShuffle3["abcd", 2]

"bacd"

stringShuffle3["abcdefghij", 2]

"bacdefghij"

stringShuffle3["abcdefghij", 4]

"dcbaefghij"


4. Alternatively, use StringReplace and StringReverse to define an operator:

ClearAll[stringShuffle4]
stringShuffle4 = StringReplace[StartOfString ~~ # -> StringReverse @ #] &;

stringShuffle4["ab"] @ "abcdefghij"

"bacdefghij"

stringShuffle4["abcd"] @ "abcdefghij"

"dcbaefghij"


There's ResourceFunction["StringFunction"] in the WFR. This gets you something resembling your operator form:

perm[s_] := {s[], s[], Sequence @@ s[[3 ;;]]}

p = ResourceFunction["StringFunction"][perm]

p["abcd"] (* bacd *)
p["uvxyzw"] (* vuxyzw *)


Taking a hint from @yarchik's comment:

Break the string s down into characters, TakeDrop the first N characters; and then reverse the first list.

reverseFirstN[s_String, n_Integer ] := Module[{t, u},
{t, u} = TakeDrop[Characters[s], n];
StringJoin[Reverse[t], u]
]


Test:

Table[reverseFirstN["abcdefghijkl", n], {n, 1, 10}] // TableForm Edit: OR maybe you want the specified substrings to swap places:

Pab[s_String, a_String, b_String] := Module[{},
StringReplace[s, {a -> b, b -> a}]
]

Pab["abcdabcd", "a", "b"]


"bacdbacd"

Pab["abracadabra xoxo", "ab", "x"]


Using Permute and Cycles:

 p[a_,b_]:=With[{x=StringSplit[#,""], as=ToString[a],bs=ToString[b]},
StringJoin@Permute[x,Cycles[{Flatten[{Position[x,as],Position[x,bs]}]}]]]&

pf[list_]:=FoldList[p[Sequence@@#2][#1]&,#,list]&


Examples

p[x,y]@p[x,a]@p[y,a]@"xya" (* ayx *)
p[y,a]@p[x,a]@p[x,y]@"xya" (* ayx *)

pf[{{x,y},{x,a},{y,a}}]@"xya"
(* {xya, yxa, yax, ayx} *)

pf[{{a,b},{c,d}}]@"abcd"


Extending:

 p[a_,b_,c_]:=With[{x=StringSplit[#,""], as=ToString[a],bs=ToString[b],cs=ToString[c]},
StringJoin@Permute[x,
Cycles[{Flatten[{Position[x,as],Position[x,bs],Position[x,cs]}]}]]]&


Examples

p[d,a]@p[c,a,d]@"abcd" (* cbad *)

pf[{{c,a,d},{d,a}}]@"abcd"

Permute[StringSplit["abcd",""], Cycles[{{1, 2}}]]//StringJoin