1
$\begingroup$

How to implement foo function which works like this:

foo @ "abcdef" 
"fdbace"

Steps: "bacdef", "cabdef", "dbacef", "ecabdf", "fdbace"

Reverse the first two letter of the string "abcdef" which will give "bacdef". Then take this as the new string and reverse the first 3 letter. Similarly, proceed for all the characters of the string.

$\endgroup$
2

3 Answers 3

11
$\begingroup$
s = "abcdef";

FoldList[
 StringJoin[
   StringReverse[StringTake[#1, {1, #2}]],
   StringTake[#1, {#2 + 1, -1}]
   ] &,
 s,
 Range[2, StringLength[s]]
 ]

{"abcdef", "bacdef", "cabdef", "dbacef", "ecabdf", "fdbace"}

$\endgroup$
4
  • $\begingroup$ I'm actually surprised at how efficient this is. I would have assumed the fastest way would be to work on the ToCharacterCode processed byte data in some in-place way but this is actually much faster, even without all of the FromCharacterCode post-processing. On a string of length 5000 it's actually faster even than in place reversal of the bytes themselves in an array which really surprised me. To add to that, it's even faster than the corresponding code using Reverse and Part on the list of bytes which has all sorts of odd implications. $\endgroup$
    – b3m2a1
    Commented Oct 1, 2018 at 0:02
  • 1
    $\begingroup$ @b3m3a1 Yeah, I was also somewhat surprised when I tried to optimize the code. Usually, String operations in Mathematice tend to be rather slow... $\endgroup$ Commented Oct 1, 2018 at 0:11
  • $\begingroup$ I wonder what part is the real holdup. I'm really surprised that working with packed arrays of integers is slower than working with strings. Also it seems writing your solution with StringDrop is also slower than StringTake[#1, {#2 + 1 ;;}] which is again very surprising. The specially made operation should be the fastest one, to my eyes. $\endgroup$
    – b3m2a1
    Commented Oct 1, 2018 at 0:15
  • 2
    $\begingroup$ It turns out String is really fast now $\endgroup$
    – b3m2a1
    Commented Oct 1, 2018 at 0:56
3
$\begingroup$
FoldList[StringReplace[#,  StartOfString ~~ p : Repeated[_, {#2}] :> 
  StringReverse[p]] &, "abcdef" , Range[2, 6]]

{"abcdef", "bacdef", "cabdef", "dbacef", "ecabdf", "fdbace"}

Also

ClearAll[f1, f2]
f1[k_] := Module[{c = TakeDrop[Characters[#], k]}, 
   StringJoin[c[[1]][[-1 ;; 1 ;; -2]], c[[1]][[1 + Boole[OddQ[k]] ;; ;; 2]], c[[2]]] ] &
f2 = Table[f1[k]@# , {k, StringLength @ #}] &;

f2 @ "abcdef"

{"abcdef", "bacdef", "cabdef", "dbacef", "ecabdf", "fdbace"}

$\endgroup$
3
$\begingroup$

Another way:

Block[{k = 1, s = "abcdef"},
      NestList[StringReplacePart[#, StringReverse[StringTake[#, ++k]], {1, k}] &,
               s, StringLength[s] - 1]]
   {"abcdef", "bacdef", "cabdef", "dbacef", "ecabdf", "fdbace"}
$\endgroup$

Your Answer

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