24
\$\begingroup\$

Substitute a string with itself

Your goal is to substitute a string with itself by replacing each character in the original string with the one before it, starting with the first character and wrapping around. Here are some examples to show what I mean:

1st example:

Input: program
Output: apgopra
How:
Program -> mrogram (replace p by m in program)
-> mpogpam (replace r by p in mrogram)
-> mprgpam (replace o by r in mpogpam)
-> mpropam (replace g by o in mprgpam)
-> mpgopam (replace r by g in mpropam)
-> mpgoprm (replace a by r in mpgopam)
-> apgopra (replace m by a in mpgoprm)

2nd example:

Input: robot
Output: orbro
How:
Robot -> tobot (replace r by t in robot)
-> trbrt (replace o by r in tobot)
-> trort (replace b by o in trbrt)
-> trbrt (replace o by b in trort)
-> orbro (replace t by o in trbrt)

3rd example:

Input: x
Output: x
How:
x -> x (replace x by x in x)

4th example:

Input: xy
Output: xx
How:
xy -> yy (replace x by y in xy)
-> xx (replace y by x in yy)

Sidenotes:

  • The string x will only contain lowercase alphanumeric characters and spaces
  • This is so shortest code in bytes wins!
xnor
150k26 gold badges287 silver badges676 bronze badges
asked Oct 25, 2015 at 12:25
\$\endgroup\$
2
  • \$\begingroup\$ Do my edits match your original idea? \$\endgroup\$ Commented Oct 25, 2015 at 12:37
  • \$\begingroup\$ Seems fine, I hope people understand that every round they basically encrypt an encrypted string by replacing characters every round. The examples make this clear, so I think they will. \$\endgroup\$ Commented Oct 25, 2015 at 12:40

17 Answers 17

19
\$\begingroup\$

CJam, 11 bytes

q__1m>.{er}

Test it here.

Explanation

q__ e# Read input and make two copies.
1m> e# Rotate the second copy one character to the right.
.{er} e# For each pair of characters from the second and third string,
 e# replace occurrences of the first with the second.
answered Oct 25, 2015 at 12:59
\$\endgroup\$
9
\$\begingroup\$

TeaScript, 17 bytes (削除) 19 (削除ここまで) (削除) 21 (削除ここまで) (削除) 24 (削除ここまで)

TeaScript is JavaScript for golfing

xd(#lg(i,xC(1#a))

Nice and short

Try it online (watch for trailing whitespace in the input)

Ungolfed & Explanation

x.reduce // Reduce over input
 (# // Anonymous function expands to ((l,i,a)=>
 l.g( // global replace...
 i // replace var i with...
 x.cycle(1) // Cycle x 1
 [a] // At position a
 )
 )
answered Oct 25, 2015 at 15:17
\$\endgroup\$
8
\$\begingroup\$

JavaScript ES6, 69 bytes

s=>[...s].reduce((p,c,i)=>p.replace(RegExp(c,'g'),s.slice(i-1)[0]),s)

F=s=>[...s].reduce((p,c,i)=>p.replace(RegExp(c,'g'),s.slice(i-1)[0]),s)
input.oninput=()=>output.innerHTML=F(input.value)
#input, #output {
 width: 100%;
}
<textarea id='input' rows="5">
</textarea>
<div id="output"></div>

answered Oct 25, 2015 at 14:13
\$\endgroup\$
6
  • 3
    \$\begingroup\$ You can skip the F= in your byte count. \$\endgroup\$ Commented Oct 25, 2015 at 15:47
  • \$\begingroup\$ @Ypnypn Thanks never know what to do when they don't specify this stuff \$\endgroup\$ Commented Oct 25, 2015 at 23:34
  • \$\begingroup\$ s.slice(i-1)[0] is not equal to s.slice(i-1,i) ? \$\endgroup\$ Commented Oct 26, 2015 at 11:25
  • 1
    \$\begingroup\$ @edc65 No not when i=0 \$\endgroup\$ Commented Oct 26, 2015 at 11:28
  • \$\begingroup\$ There's now a replaceAll method that can save some bytes. I'm not sure which ES version introduced it, so it might not be ES6 then. s=>[...s].reduce((p,c,i)=>p.replaceAll(c,s.slice(i-1)[0]),s), 60 bytes. \$\endgroup\$ Commented Nov 12, 2020 at 9:07
3
\$\begingroup\$

Ruby, (削除) 50 (削除ここまで) 48 bytes

->s{t=s.dup;t.size.times{|i|t.tr!s[i],s[i-1]};t}

Test:

f=->s{t=s.dup;t.size.times{|i|t.tr!s[i],s[i-1]};t}
f["program"]
=> "apgopra"
answered Oct 25, 2015 at 13:05
\$\endgroup\$
3
\$\begingroup\$

Mathematica, (削除) 89 (削除ここまで) (削除) 75 (削除ここまで) (削除) 74 (削除ここまで) 57 bytes

""<>Fold[#/.#2&,c=Characters@#,Thread[c->RotateRight@c]]&
answered Oct 25, 2015 at 12:51
\$\endgroup\$
2
  • \$\begingroup\$ ""<>Fold[#/.#2&,c=Characters@#,Thread[c->RotateRight@c]]& \$\endgroup\$ Commented Oct 25, 2015 at 16:20
  • \$\begingroup\$ @alephalpha Thanks, I tried that with Transpose and failed. \$\endgroup\$ Commented Oct 25, 2015 at 16:24
3
\$\begingroup\$

Pyth, 13 bytes

u:G.*HC.>Bz1z

Try it online. Test suite.

answered Oct 25, 2015 at 18:07
\$\endgroup\$
3
\$\begingroup\$

k2 - 17 char

Function taking 1 argument.

{_ssr/[x;x;-1!x]}

k2 has a builtin called _ssr for String Search and Replace. _ssr[x;y;z] will find y in x and replace it with z. So we use / to fold this functionality over each replacement we want to make. For those unfamiliar with folding (as in functional programming), essentially _ssr/[x; (y1; y2; y3); (z1; z2; z3)] becomes _ssr[_ssr[_ssr[x; y1; z1]; y2; z2]; y3; z3]. Strings are lists of their characters, so we may simply rotate the input back a step and get the replacements, and plug right in.

 {_ssr/[x;x;-1!x]} "program"
"apgopra"
 {_ssr/[x;x;-1!x]} "robot"
"orbro"
 {_ssr/[x;x;-1!x]} (,"x") / one-letter strings are ,"x" and parens are required
,"x"
 {_ssr/[x;x;-1!x]} "xy"
"xx"
answered Oct 26, 2015 at 1:24
\$\endgroup\$
2
\$\begingroup\$

Haskell, 76 bytes

[]#_=[];(x:y)#g@(a,b)|x==a=b:y#g|2>1=x:y#g;h x=foldl(#)x$zip x$last x:init x

Too bad, Haskell doesn't even have a build-in substitution function.

answered Oct 26, 2015 at 10:28
\$\endgroup\$
2
\$\begingroup\$

PHP, 76 bytes

function($s){$f=str_split;echo str_replace($f($s),$f(substr($s,-1).$s),$s);}

Here is the ungolfed version:

function selfSubstitute($originalString)
{
 $shiftedString = substr($originalString, -1) . $originalString;
 $splitOriginalString = str_split($originalString);
 $splitShiftedString = str_split($shiftedString);
 echo str_replace($splitOriginalString, $splitShiftedString, $originalString);
}
answered Oct 26, 2015 at 12:21
\$\endgroup\$
2
\$\begingroup\$

Python, (削除) 67 (削除ここまで) (削除) 64 (削除ここまで) (削除) 62 (削除ここまで) 57 Bytes

Straightforward solution, will look into something to shorten this. Thanks to @RandyC for saving 5 bytes.

c=input()
for x in zip(c,c[-1]+c):c=c.replace(*x)
print c

Input should be in quotes.

answered Oct 25, 2015 at 16:45
\$\endgroup\$
2
  • \$\begingroup\$ You can save a few bytes dropping the [:-1] since zip truncates to the shortest iterable. \$\endgroup\$ Commented Oct 26, 2015 at 21:24
  • \$\begingroup\$ @RandyC Wow, good call! Thanks. \$\endgroup\$ Commented Oct 27, 2015 at 2:18
2
\$\begingroup\$

Haskell, 58 bytes

r(x,y)c|x==c=y|0<1=c;f s=foldl(flip$map.r)s.zip s$last s:s

Pretty similar to Christian's solution, but using map and the fact that zip ignores superfluous elements if the lists are of unequal length. It folds through the list of replacements (on the form (from,to)), updating the string by mapping the hand written replacement function r on each letter.

The expression flip$map.r was derived using LambdaBot's "Pointless" plugin.

answered Oct 27, 2015 at 3:02
\$\endgroup\$
2
\$\begingroup\$

Jelly, (削除) 10 (削除ここまで) (削除) 9 (削除ここまで) 7 bytes

ṙ-ż@y@ƒ

Try it online!

Having seen caird's y-based solution, I spent several hours trying to use matrix multiplication instead, but eventually I took a crack at y and arrived at this.

Speaking of caird's solution, I was about to pose the question to JHT of how to outdo J_.ịƲU for "obtaining pairs of elements from the input followed by the elements preceding them, wrapping around", but as I wrote that whole thing out I realized I never did actually try using ż!

The edit history contains some nice old explanations if anyone wants to read them.

ṙ Rotate the input left
 - by -1.
 ż@ Zip the input with the rotated input.
 ƒ Starting with the input, reduce the resulting pairs by
 y@ substitution.
answered Nov 13, 2020 at 12:43
\$\endgroup\$
1
\$\begingroup\$

J, 18 bytes

rplc~/@,~|.,.1|.|.

Try it online!

answered Nov 12, 2020 at 11:47
\$\endgroup\$
1
\$\begingroup\$

Jelly, 15 bytes

żṙ-,ドルμ,Ḣy\\/ḷ/¿

Try it online!

Jelly sucks at strings

How it works

żṙ-,ドルμ,Ḣy\\/ḷ/¿ - Main link. Takes a string S on the left
 $ - Group the previous two links together:
 - - -1
 ṙ - Rotate S 1 unit to the right
ż - Zip S with rotated S; Call this M
 , - Pair with S; [M, S]
 μ - Begin a new link with this pair as the argument
 \ - Group the previous two links together as a dyad f(p, s):
 \ - Group the previous two links together as a dyad g(p, s):
 Ḣ - Remove the first pair in p and use it; [c, t]
 y - Replace c with t in s
 , - Yield a pair with the modified p and the replaced s
 ¿ - While:
 ḷ/ - The first element is truthy
 / - Run f(M, S)
answered Nov 11, 2020 at 23:34
\$\endgroup\$
2
  • \$\begingroup\$ Doesn't Jelly have transliterate built-in? \$\endgroup\$ Commented Nov 12, 2020 at 9:19
  • 1
    \$\begingroup\$ @Shaggy Yeah, that’s the y. Unfortunately the issue is that unlike e.g. the k answer, Jelly isn’t a fan of reducing by y to perform repeated transliteration, so we need to go through the whole charade of a while loop instead \$\endgroup\$ Commented Nov 12, 2020 at 9:51
1
\$\begingroup\$

Japt, 5 bytes

dUíUé

Try it

dUíUé :Implicit input of string U
d :For each pair XY in the following string, recursively replace X with Y
 Uí : Interleave U with
 Ué : U rotated right
answered Nov 12, 2020 at 8:35
\$\endgroup\$
0
\$\begingroup\$

Perl 5 -pF, 34 bytes

for$a(0..$#F){s/$F[$a]/$F[$a-1]/g}

Try it online!

answered Nov 12, 2020 at 23:57
\$\endgroup\$
0
\$\begingroup\$

Brachylog, 29 bytes

⟨tc≡⟩⟨gcs2f⟩{gtz{tv&th|h}m}lb

Try it online!

 c Concatenate
 t the last item of the input
⟨ ≡⟩ with the input.
 c Concatenate
 g that result in a singleton list
 ⟨ s2f⟩ with a list of its length-2 substrings.
 ... b Remove the extra element from the final result.
{ }l Left fold:
 gtz zip each element of the first element with the entire second element,
 { }m and for each of those pairs:
 tv the last element of both is the same
 &th and the first element of the last element of the pair
 | is the output, or
 h the first element of the pair is the output.
answered Nov 16, 2020 at 7:41
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.