5
$\begingroup$

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:

After reading answers I felt like I did not ask my question properly.

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[1]<>S[2] to change specific ones. Is there a way I can implement these?

$\endgroup$
5
  • 3
    $\begingroup$ It is much easier to manipulate lists, such as {1,2,3,4}. You can convert them to strings as desired. $\endgroup$
    – yarchik
    Sep 8, 2021 at 18:36
  • 1
    $\begingroup$ What do you want $P^{ya}$"yxa" to return? Should it be "yxa" or "axy"? $\endgroup$
    – Carl Woll
    Sep 15, 2021 at 18:13
  • $\begingroup$ @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}$. $\endgroup$
    – user824530
    Sep 16, 2021 at 0:25
  • 1
    $\begingroup$ My answer returns "axy", while the accepted answer returns "yxa". This is why I asked. $\endgroup$
    – Carl Woll
    Sep 16, 2021 at 2:55
  • $\begingroup$ @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. $\endgroup$
    – user824530
    Sep 17, 2021 at 11:23

6 Answers 6

5
$\begingroup$

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"

$\endgroup$
1
  • $\begingroup$ Thank you so much. This is beautiful. $\endgroup$
    – user824530
    Sep 15, 2021 at 18:09
8
$\begingroup$

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"

Original answer:

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"
$\endgroup$
4
$\begingroup$

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

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

p = ResourceFunction["StringFunction"][perm]

p["abcd"] (* bacd *)
p["uvxyzw"] (* vuxyzw *)
$\endgroup$
4
$\begingroup$

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

enter image description here

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"]

xracadxra aboabo

$\endgroup$
2
$\begingroup$

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 *)
p[c,d]@p[a,b]@"abcd" (* badc *) 

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

pf[{{a,b},{c,d}}]@"abcd"
(* {abcd, bacd, badc} *) 

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"
(* {abcd, cbda, cbad} *) 

Original Answer:

Permute[StringSplit["abcd",""], Cycles[{{1, 2}}]]//StringJoin
(* bacd *)
$\endgroup$
1
$\begingroup$
str = "abcd";

Using SubsetMap (new in 12.0)

f[p__][s_] := StringJoin @ SubsetMap[RotateLeft, Characters[s], {p}]

Swap elements 1 and 3

f[1, 3] @ str

"cbad"

Apply multiple permutations

f[1, 3] @ f[1, 3] @ str

"abcd"

Move element 1 to 3rd place

f[1, 2, 3] @ str

"bcad"

Apply multiple permutations

f[1, 2] @ f[4, 3, 2, 1] @ str == f[4, 3, 2] @ str

True

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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