7
\$\begingroup\$

This is my first time here at Code Golf SE so feel free to add your input/advice/suggestions to improve my post if necessary. The week after my computer science exam, the solutions were publicly published. One problem had a 45 line example solution but my solution was only 18 lines, (which I was very proud of), but I bet you guys here at code golf SE can do better.

Here are the requirements:

  • Takes two inputs, string1 and string2.
  • Delete the first occurrence of string2 found in the string1.
  • Add string2 in reverse order to the beginning of string1, and
  • Add string2 in reverse order to the end of the string1.
  • If string2 does not occur in string1, do not modify string1.
  • Output the modified string1

Example:

Input:

batman
bat

thebatman
bat

batman
cat

Output:

tabmantab

tabthemantab

batman

Note: The problem was intended to handle basic inputs. Assume all expected inputs are restricted to characters A-Z, numbers, or other special characters visible on your keyboard. It does not need to handle tabs or newlines.

Submissions with shortest byte counts in each language win.

\$\endgroup\$
10
  • 3
    \$\begingroup\$ Can you give an example test case where string 2 doesn't occur in string 1? Also - which characters can appear in the string? Printable ASCII? Tab? Newlines? \$\endgroup\$
    – DELETE_ME
    Mar 6, 2018 at 6:13
  • \$\begingroup\$ @user202729 Input "batman, robin" has output "batman" \$\endgroup\$
    – Ryan
    Mar 6, 2018 at 6:17
  • \$\begingroup\$ Out of curiosity, which language did you use in the exam? \$\endgroup\$
    – DELETE_ME
    Mar 6, 2018 at 6:26
  • 2
    \$\begingroup\$ And an example where string2 contains characters that are special in a regex and make naive s/string2// fail \$\endgroup\$
    – Ton Hospel
    Mar 6, 2018 at 7:19
  • 2
    \$\begingroup\$ Perhaps a test case containing the second input multiple times, since we only should replace the first? Something like: "batman_and_his_bat", "bat""tabman_and_his_battab" \$\endgroup\$ Mar 6, 2018 at 9:48

20 Answers 20

5
\$\begingroup\$

Stax, 16 11 bytes

ÄE┘¢8·╦Ωb•∩

Run and debug it online

The corresponding ascii representation of the same program is this.

Y#xyz|eyr|Sx?

This fixes the bugs in original version. It uses conditionals and stuff.

Y                   Save 2nd input in y.  Now the two inputs are x and y.
 #                  Occurrences of y in x. (a)
  xyz               x, y, ""
     |e             replace first occurrence
       yr|S         surround with y reversed. (b)
           x        first input. (c)
            ?       a ? b : c

The result is printed implicitly.

\$\endgroup\$
3
\$\begingroup\$

Python, 55 bytes

lambda s,t:s.replace(t,'',1).join(2*[t[::-1]*(t in s)])

Try it online!

Using join to get the a+b+a pattern. This lets us write expression for a only once while still using a lambda. Compare:

Python 2, 57 bytes

def f(s,t):r=t[::-1]*(t in s);print r+s.replace(t,'',1)+r

Try it online!

\$\endgroup\$
3
\$\begingroup\$

APL (Dyalog Unicode), 36 bytesSBCS

Look ma, no regex!

Anonymous infix lambda, taking string2 as left argument and string1 as right argument. Assumes ⎕IO (Index Origin) to be 0, which is default on many systems.

{r,⍵[(⍳≢⍵)~(f⍳1)+⍳≢⍺],r←⌽⍺/⍨∨/f←⍺⍷⍵}

Try it online!

{} "dfn"; is left argument, is right argument; e.g. "bat" and "manbatmanbat":

⍺⍷⍵ find where string2 begins in string1; [0,0,0,1,0,0,0,0,0,1,0,0]

f← assign to f (find)

∨/ OR-reduction (does string2 occur at all?); 1

⍺/⍨ use that to compress string2 ("" if not found); "bat"

 reverse that; "tab"

r← assign to r (reverse)

⍵[], prepend string2 indexed by the following indices:

  ≢⍵ the length of string2; 3

   the indices of that; [0,1,2]

  ()+ add the following to that:

   f⍳1 index of first 1 in f; 3

  Now we have the indices to be removed; [3,4,5]

  ()~ the following indices except those indices:

   ≢⍵ length of string2; 12

    the indices of that; [0,1,2,3,4,5,6,7,8,9,10,11]

  Now we have the indices we want to keep; [0,1,2,6,7,8,9,10,11]

 This gives us the remaining parts of string1 followed by a reversed string2; "manmanbattab"

r, prepend r to that; "tabmanmanbattab"

\$\endgroup\$
3
\$\begingroup\$

C#, 148 bytes

using System.Linq;using System.Text.RegularExpressions;(a,b)=>a==(a=new Regex(Regex.Escape(b)).Replace(a,"",1))?a:(b=string.Concat(b.Reverse()))+a+b
\$\endgroup\$
4
  • 2
    \$\begingroup\$ Perhaps include a tio link? (I edited your post to capitalize C# and add syntax highlighting.) \$\endgroup\$
    – Οurous
    Mar 6, 2018 at 8:39
  • 2
    \$\begingroup\$ Welcome to PPCG, and nice first answer! With lambdas you are allowed to leave out the types and the trailing semi-colon, but all required imports are mandatory for the byte-count I'm afraid, so it would becomes this instead: using System.Linq;(a,b)=>a==(a=new System.Text.RegularExpressions.Regex(b).Replace(a,"",1))?a:(b=string.Concat(b.Reverse()))+a+b (128 bytes). Also, as @Ourous suggested, perhaps add a TIO link to your answer. Here is an example of how it might look like. It's unfortunate the Regex import is so long in .NET... :( \$\endgroup\$ Mar 6, 2018 at 9:30
  • 1
    \$\begingroup\$ Hmm, it seems to fail for "this.is.a.test", ".". Expected output: ".thisis.a.test.", actual output: ".his.is.a.test.". Can be fixed like this: using System.Linq;using System.Text.RegularExpressions;(a,b)=>a==(a=new Regex(Regex.Escape(b)).Replace(a,"",1))?a:(b=string.Concat(b.Reverse()))+a+b (148 bytes). Try it online. \$\endgroup\$ Mar 6, 2018 at 11:00
  • \$\begingroup\$ Thanks Kevin.. wow, c# is impressively unsuitable for golfing.. :) I tested my code in linqpad which I guess adds some commonly used namespaces by default. And yep, missed the need to escape it as someone pointed out in your java port of my code :) I think I am gonna use JavaScript next time. Thank you very much for taking the time. \$\endgroup\$
    – lee
    Mar 6, 2018 at 11:13
3
\$\begingroup\$

Ruby, 39 38 35 bytes

-3 bytes due to a neat trick by Asone Tuhid

->x,y{(x[y]&&="")?y.reverse!+x+y:x}

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ 35 bytes \$\endgroup\$ Mar 8, 2018 at 16:36
  • \$\begingroup\$ Wow, I was thinking for ages, how to get rid of that duplicated x[y], but didn't even know this was possible \$\endgroup\$
    – Kirill L.
    Mar 8, 2018 at 17:25
  • \$\begingroup\$ It's the same idea as ||=, +=, etc. I think all a=a<op>b can be reduced to a<op>=b (or a<op>a=b in this case) if that makes sense. \$\endgroup\$ Mar 8, 2018 at 17:31
2
\$\begingroup\$

Python 3, 56 bytes

lambda s,t:[s,t[::-1]+s.replace(t,'',1)+t[::-1]][t in s]

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Retina, 35 bytes

^(.*)¶(.*?)\1(.*)
¶$^$1$2$3$^$1
0A`

Try it online! $^ is new in Retina 1 and reverses its argument which is just what's needed here.

\$\endgroup\$
0
2
\$\begingroup\$

Java 8, 126 113 bytes

(a,b)->a.equals(a=a.replaceFirst(java.util.regex.Pattern.quote(b),""))?a:(b=new StringBuffer(b).reverse()+"")+a+b

Port of @lee's C# .NET answer, so make sure to upvote him!

Try it online.

Old 126 byte answer:

a->b->{Object r=new StringBuffer(b).reverse();return a.contains(b)?r+a.replaceFirst(java.util.regex.Pattern.quote(b),"")+r:a;}

Try it online.

Explanation:

a->b->{                    // Method with two String parameters and String return-type
  Object r=new StringBuffer(b).reverse();
                           //  2nd input reversed
  return a.contains(b)?    //  If the 1st input contains the 2nd:
    r                      //   Output the reversed 2nd input
     +a.replaceFirst(java.util.regex.Pattern.quote(b),"") 
                           //   Removed the first occurrence of the 2nd in the 1st input,
                           //   escaping any characters like dots, pluses, etc.
                           //   and then append that to the result
     +r                    //   appended with the reversed 2nd input again
   :                       //  Else:
    a;}                    //   Simply output the 1st input
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Fails with b = "..." ("Assume all expected inputs are restricted to characters A-Z, numbers, or other special characters visible on your keyboard." : . is a special character visible on every keyboard) \$\endgroup\$ Mar 6, 2018 at 10:42
1
\$\begingroup\$

Perl 5 + -pl, 38 34 bytes

$s=<>;s/\Q$s//&&s/^|$/reverse$s/ge

-4 thanks to Ton Hospel

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Good method but can be golfed a bit more: -pl $s=<>;s/$s//&&s/^|$/reverse$s/ge. Both versions really need to use s/\Q$s// though since characters like * and . seem allowed \$\endgroup\$
    – Ton Hospel
    Mar 6, 2018 at 7:12
1
\$\begingroup\$

05AB1E, 12 bytes

DIåiIõ.;IR.ø

Try it online!

Explanation

D             # duplicate 1st input
 Iåi          # if 2nd input is in first input
    Iõ.;      # replace the first occurrence of 2nd input with the empty string
        IR.ø  # surround with 2nd input reversed
\$\endgroup\$
1
  • \$\begingroup\$ Only other thing I can think of is 13-bytes: õ.;©Ê²si®¹R.ø but it's pretty different order-wise. \$\endgroup\$ Mar 6, 2018 at 15:25
1
\$\begingroup\$

Javascript (ES6), 69 65 64 bytes

x=>y=>x.match(y)?(k=[...y].reverse().join``)+x.replace(y,'')+k:x

Try it online!

\$\endgroup\$
4
  • 1
    \$\begingroup\$ Welcome to PPCG! / (1) In the way how we normally count byte count, the m= is not counted if you don't use it in the function (i.e., it doesn't call itself). (2) You can save a byte by currying. \$\endgroup\$
    – DELETE_ME
    Mar 6, 2018 at 14:01
  • \$\begingroup\$ Also you may find Tips for golfing in Javascript useful. \$\endgroup\$
    – DELETE_ME
    Mar 6, 2018 at 14:01
  • \$\begingroup\$ You can use [...y].reverse().join`` to reverse a string, save 2 bytes. \$\endgroup\$
    – DELETE_ME
    Mar 6, 2018 at 14:06
  • \$\begingroup\$ Doesn't work when y contain |? \$\endgroup\$
    – l4m2
    Mar 7, 2018 at 4:22
1
\$\begingroup\$

K4, 36 bytes

Solution:

{$[#s:x ss y;r,(x_/(#y)#*s),r:|y;x]}

Examples:

q)k){$[#s:x ss y;r,x_/(#y)#*s,r:|y;x]}["batman";"bat"]
"tabman"
q)k){$[#s:x ss y;r,(x_/(#y)#*s),r:|y;x]}["batman";"bat"]
"tabmantab"
q)k){$[#s:x ss y;r,(x_/(#y)#*s),r:|y;x]}["thebatman";"bat"]
"tabthemantab"
q)k){$[#s:x ss y;r,(x_/(#y)#*s),r:|y;x]}["batman";"cat"]
"batman"
q)k){$[#s:x ss y;r,(x_/(#y)#*s),r:|y;x]}["batbatbat";"bat"]
"tabbatbattab

Explanation:

If string 2 (y) is found in string 1 (x) then drop first indices of first occurrence.

{$[#s:x ss y;r,(x_/(#y)#*s),r:|y;x]} / the solution
{                                  } / lambda with implicit x,y
 $[         ;                   ; ]  / $[condition;true;false]
      x ss y                         / string-search for y in x
    s:                               / save result as s
   #                                 / count length
                              |y     / reverse (|) y
                            r:       / save as r
                           ,         / join with
               (          )          / do this together
                        *s           / first (*) s
                       #             / take
                   (#y)              / length of y
                x_/                  / drop (_) over (/)
             r,                      / join with r
                                 x   / (else) return x
\$\endgroup\$
1
\$\begingroup\$

Jelly, 18 bytes

œṣ⁹Ḣ;jɗ⁹ṭṚ};Ṛ}ðẇ@¡

Try it online!

Full program.

\$\endgroup\$
0
1
\$\begingroup\$

Javascript 85 bytes

a=>b=>a.includes(b)?[...b].reverse().join``+a.replace(b,'')+[...b].reverse().join``:a

If someone knows how to avoid using split('').reverse().join('') for reversing string, please let me know

f=a=>b=>a.includes(b)?[...b].reverse().join``+a.replace(b,'')+[...b].reverse().join``:a


console.log(f('batman')('bat'))

console.log(f('thebatman')('bat'))

console.log(f('batman')('cat'))

\$\endgroup\$
2
  • 1
    \$\begingroup\$ for help, you can't get much better than the Tips for golfing in javascript, and I'm sure somebody will come along to help -- I don't know javascript. \$\endgroup\$
    – Giuseppe
    Mar 6, 2018 at 18:24
  • \$\begingroup\$ There's really no better way to reverse a string. What you could do is ...?(c=[...b].reverse().join``)+a.replace(b,'')+c:a to save quite a few bytes. \$\endgroup\$ Mar 6, 2018 at 21:15
1
\$\begingroup\$

Javascript, ES6 - 73 bytes

b=x=>y=>{v=[...y].reverse().join``;u=x.replace(y,"");alert(u==x?x:v+u+v)}
\$\endgroup\$
4
  • \$\begingroup\$ please support me to improve it! \$\endgroup\$
    – NTCG
    Mar 6, 2018 at 10:19
  • 1
    \$\begingroup\$ Several of the JavaScript and ES6 tips will let you shave off a number of bytes. \$\endgroup\$
    – Neil
    Mar 6, 2018 at 11:03
  • \$\begingroup\$ Also, we format code blocks with 4-spaces indentation. See this. \$\endgroup\$
    – DELETE_ME
    Mar 6, 2018 at 11:31
  • \$\begingroup\$ @user202729 thank you for reminding me! \$\endgroup\$
    – NTCG
    Mar 7, 2018 at 3:13
0
\$\begingroup\$

Python 2, 62 Bytes

def f(a,b):b*=b in a;a=a.replace(b,"",1);b=b[::-1];print b+a+b
\$\endgroup\$
0
\$\begingroup\$

Jelly, 21 20 bytes

œṣµḢ;j⁹$ɓ;;@ðU}
ç¹w?

Try it online!


Ouch! Why can other languages get 11~12 bytes? Am I doing something wrong?

And finally, I think I know how chain separators works...

œṣµḢ;j⁹$ɓ;;@ðU}   Helper link (dyadic). General structure:
œṣ                <dyad>                    - given x and y, split x at
                                              sublists equal to y.
   Ḣ;j⁹$                <monad>             - given x, join with y except at
                                              first index.
         ;;@                   <dyad>       - given x and y, return y+x+y.
                                              Note that this link is flipped.
             U}                      <dyad> - reverse right argument.

ç¹w?    Main link. Evaluate the last link if the second input is a substring
        of the first input, otherwise - apply identity (do nothing).
\$\endgroup\$
0
\$\begingroup\$

SNOBOL4 (CSNOBOL4), 73 bytes

	S =INPUT
	T =INPUT
	S T =	:F(O)
	T =REVERSE(T)
	S =T S T
O	OUTPUT =S
END

Try it online!

What's a regular expression?

\$\endgroup\$
0
\$\begingroup\$

AWK, 85 bytes

{for(;x++<N=split($0,a,"");)p=a[x]p;$0=NR%2?L=$0:sub($0,"",L)?p L p:L}!(NR%2)

Try it online!

Input is: primary string on odd-lines, replacement on even lines. Replacement is case sensitive.

\$\endgroup\$
0
\$\begingroup\$

Python 3, 58 bytes

def f(a,b):z=(b in a)*b[::-1];return z+a.replace(b,'',1)+z
\$\endgroup\$

Your Answer

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

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