17
\$\begingroup\$

Background

I am currently in an AP Comp Sci A: Java class, and I want to start some of my friends on code golfing. I have a challenge from the course, and I would like to see how many bytes the community can do this challenge in.

Challenge details:

Given two input strings, the main string and the pivot string, do the following:

If the pivot string is exactly once as a substring of the main string, the part of the main string that comes before the pivot string shall be swapped with the part that comes after, while preserving the order within said subtrings being swapped.

For example:

If the pivot string is empty or the pivot string is not found within the main string, the program does not have to have defined behavior.

If there is more than one instance of the pivot string, the split should occur at the first and only the first instance of the pivot.

Examples: Given the main string OneTwoThreeTwoOne and the pivot string Two, the output should be ThreeTwoOneTwoOne.

Given the main string 1Two2Two3Two4 and pivot Two, the output should be 2Two3Two4Two1.

Given the main string OneTwoThree and the pivot string "Two", the output should be ThreeTwoOne. Given the main string the rabbit is faster than the turtle and the pivot string

 is faster than 

(note the single space trailing and preceding), the output should be the turtle is faster than the rabbit.

Given the main string 1-2-3-4-5-6 and the pivot -, the output should be 2-3-4-5-6-1.

Afterword:

This is my first ever question on code golf, so if you have suggestions or constructive criticism, then feel free to say so.

Additionally, my code for this project (written in Java because the course focuses on that) can be found below. If you have any tips, I'd love to see them. Its currently 363 bytes, but I bet you guys can come up with much better and smaller solutions.

import java.util.Scanner;interface Main{static<T>void D(T f){System.out.println(f);}static void main(String[]A){Scanner s=new Scanner(System.in);D("Enter the first String:");String a=s.nextLine();D("Enter the pivot String:");String p=s.nextLine();if(p.isEmpty()|!a.contains(p)){D("Error: Pivot String not found.");return;}String w[]=a.split(p,2);D(w[1]+p+w[0]);}}

Note: The text for the inputs and for the case that the pivot string is not found is mandatory for the original assignment, but not for this challenge.

\$\endgroup\$
4
  • \$\begingroup\$ What is the expected output for pivot='-' and main='1-2-3-4-5-6'? Most submissions output 2-3-4-5-6-1 for this, but as I understand the challenge it should be 2-1-3-4-5-6. \$\endgroup\$
    – ovs
    Dec 8, 2017 at 18:19
  • \$\begingroup\$ It should only split the string on the first pivot. So intended output should be 2-3-4-5-6-1. \$\endgroup\$ Dec 8, 2017 at 18:27
  • 3
    \$\begingroup\$ By the way, you can use the sandbox next time. \$\endgroup\$ Dec 8, 2017 at 19:25
  • \$\begingroup\$ I think the emphasis "while preserving the order within said subtrings being swapped" just made it more confusing. I already understand it that way, but the wording made it confusing if that's what you meant. \$\endgroup\$
    – kamoroso94
    Dec 9, 2017 at 1:17

29 Answers 29

7
\$\begingroup\$

Mathematica, 42 bytes

Reverse@StringSplit[##,2]~StringRiffle~#2&

Try it online!

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

Jelly, 6 bytes

œṣṙ1j⁴

Try it online!

Explanation

œṣṙ1j⁴  Main Link
œṣ      Split around sublists equal to the pivot
  ṙ1    Rotate left by one
    j⁴  Rejoin on the pivot
\$\endgroup\$
4
  • \$\begingroup\$ Wow, any chance of an explanation? That's phenomenal! \$\endgroup\$ Dec 8, 2017 at 18:06
  • \$\begingroup\$ @ThePlasmaRailgun It's not that phenomenal, in fact :P - Jelly has useful built-ins: œṣ is "split x around sublists equal to y", ṙ1 rotates the array one place to the left and j⁴ joins with the second input. \$\endgroup\$
    – Mr. Xcoder
    Dec 8, 2017 at 18:12
  • \$\begingroup\$ @ThePlasmaRailgun Adding explanation now. But for Jelly that's not even extremely impressive xD \$\endgroup\$
    – hyper-neutrino
    Dec 8, 2017 at 18:14
  • \$\begingroup\$ Nice. I love it. \$\endgroup\$ Dec 8, 2017 at 18:31
6
\$\begingroup\$

Python 2, 37 39 bytes

lambda a,b:b.join(a.split(b,1)[::-1])

Where a is the main string and b is the pivot string.

Try it online!

\$\endgroup\$
3
  • 2
    \$\begingroup\$ Change split(b) to split(b,1) to specify that you only want to split on the first occurance. \$\endgroup\$
    – mypetlion
    Dec 8, 2017 at 18:27
  • \$\begingroup\$ @ovs, edited to work on third test case \$\endgroup\$
    – wnnmaw
    Dec 8, 2017 at 18:30
  • \$\begingroup\$ @mypetlion, I didn't know split accepted more arguments, thanks! \$\endgroup\$
    – wnnmaw
    Dec 8, 2017 at 18:30
6
\$\begingroup\$

Wolfram Language (Mathematica), 34 bytes

p#2<>p<>#&@@StringSplit[#,p,2]&

Try it online!

An unnamed, curried function which should be called with the pivot first and the main string second. E.g., if you assigned the function to a name f:

f["-"]["1-2-3-4-5-6"]
\$\endgroup\$
5
\$\begingroup\$

Ohm v2, 4 bytes

ïλ⁴j

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ @ThePlasmaRailgun Same as Jelly, just shorter built-ins \$\endgroup\$
    – Mr. Xcoder
    Dec 8, 2017 at 18:35
4
\$\begingroup\$

Perl 5, 20 + 2 (-pl) = 22 bytes

<>=~/$_/;$_="$'$_$`"

Try it online!

Takes the pivot string on the first line, then the full string on the second.

\$\endgroup\$
2
  • \$\begingroup\$ playing with arguments i found this 20 bytes solution, otherwise the /s around $_ can be removed \$\endgroup\$ Dec 8, 2017 at 19:32
  • \$\begingroup\$ also $_=~<>;$_="$'$&$"` is 20 bytes and reads arguments in the right order \$\endgroup\$ Dec 9, 2017 at 8:42
4
\$\begingroup\$

Python 2, 53 44 bytes

thanks to ThePlasmaRailgun for some bytes

p,m=input()
k=m.split(p,1)
print k[1]+p+k[0]

Try it online!

\$\endgroup\$
5
  • \$\begingroup\$ Output on your test case with pivot "Two" and string "1Two2Two3Two4" should be "2Two3Two4Two1". It should only split on the first "Two", leaving you the array ["1", "2Two3Two4Two"]. Then you can just print k[1]+p+k[0]. This should have intended behavior. \$\endgroup\$ Dec 8, 2017 at 18:23
  • \$\begingroup\$ Fixed. I'm also going to add an example test case to show people how it should be. \$\endgroup\$ Dec 8, 2017 at 18:25
  • \$\begingroup\$ @ThePlasmaRailgun for the next time you want to improve an answer just leave a comment and let the op edit it in. \$\endgroup\$
    – ovs
    Dec 8, 2017 at 18:30
  • \$\begingroup\$ @ThePlasmaRailgun thanks for your clarification \$\endgroup\$
    – ovs
    Dec 8, 2017 at 18:30
  • \$\begingroup\$ Second and third lines become k,j=m.split(p,1);print j,p,k for 38 bytes. \$\endgroup\$
    – mypetlion
    Dec 8, 2017 at 19:24
4
\$\begingroup\$

Python 2, 37 bytes

lambda a,b:b.join(a.split(b,1)[::-1])

Try it online!

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

C# (Visual C# Compiler), 56 bytes

(m,p)=>(m+p+m).Substring(m.IndexOf(p)+p.Length,m.Length)

Try it online!

\$\endgroup\$
4
\$\begingroup\$

Alice, 18 bytes

/?.?.Qz
\IoI%!oo@/

Try it online!

Explanation

/...
\...@/

This is just a framework for linear Ordinal mode (string-processing) code. Unfolding the zigzag control flow, we get:

I.I.!zo?o?%Qo

I.  Read the first string, duplicate it.
I   Read the second string (the pivot).
.!  Store a copy of the pivot on the tape.
z   Drop. Removes everything up to and including the pivot from the first string,
    so we get only the stuff after the pivot.
o   Output that.
?o  Retrieve the pivot from the tape and output it.
?%  Retrieve the pivot again and split the input around (all occurrences of)
    the pivot.
Q   Reverse the stack.
o   Output the top of the stack (i.e. the chunk in front of the first pivot).
\$\endgroup\$
4
\$\begingroup\$

SOGL V0.12, 9 5 bytes

ΘK+,∑

Try it Here!

Explanation:

Θ      split the 2nd input on the 1st one
 K     get the 1st element
  +    and add it to the end
   ,∑  join on the 1st input
\$\endgroup\$
3
\$\begingroup\$

Retina, 24 23 bytes

tanks to Martin Ender for -1 byte

(.*)¶(.*?)\1(.*)
$3$1$2

Try it online!

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

Python 2, 48 bytes

lambda s,p:p.join(s.split(p)[1:]+s.split(p)[:1])

Try it online!

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

Pyth, 8 bytes

jQ.<cEQ1

Try it here!

Explanation

jQ.<cEQ1 - Full program.

    cEQ  - Split the second input by the first input.
  .<   1 - Cyclically rotate by 1 place to the left.
jQ       - Join on the first input.
\$\endgroup\$
2
\$\begingroup\$

Charcoal, 13 bytes

≔⪪θηθ⪫Eθ§θ⊕κη

Try it online! Link is to verbose version of code. Explanation:

  θ             First input
   η            Second input
 ⪪              Split
≔   θ           Assign result
      Eθ        Map over result
           κ    Current index
          ⊕     Incremented
        §θ      Circularly index into result
     ⪫      η   Join
                Implicitly print
\$\endgroup\$
2
\$\begingroup\$

R, 63 58 57 bytes

function(M,P)sub(sub("_",P,"(.+?)(_)(.+)"),"\\3\\2\\1",M)

Try it online!

M is the main string, P is the pivot.

ovs' Retina answer indicated that I could repair my earlier attempt at a regex approach

(.+)(Pivot string)(.+)

by adding ? to the first capture group.

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

Java 8, 47 bytes

x->y->x.replaceAll("(.*?)("+y+")(.*)","$3$2$1")

Try it online

\$\endgroup\$
1
  • \$\begingroup\$ changed replaceFirst by replaceAll because 2 bytes shorter and as the regex matches the whole string replace is done only once \$\endgroup\$ Dec 9, 2017 at 8:28
2
\$\begingroup\$

JavaScript (ES6), 41 40 bytes

(s,p,[a,...r]=s.split(p))=>r.join(p)+p+a

Test cases

let f =

(s,p,[a,...r]=s.split(p))=>r.join(p)+p+a

console.log(f('the rabbit is faster than the turtle', ' is faster than '))
console.log(f('1-2-3-4-5-6', '-'))

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

J, 14 bytes

#@[}.{.@ss|.,~

How it works:

The left argument is the pivot, the right one - the string to be reversed

            ,~   appends the pivot to the string
     {.@ss       finds the positions of the pivot in the string and takes the first one
          |.     rotates the appended string to the left, so that the pivot is at the start
#@[              finds the length of the pivot string (n)
   }.            drops n characters from the begining of the rotated string

Try it online!

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

C,  106  100 bytes

i,l;f(s,p)char*s,*p;{l=strlen(p);for(i=0;strncmp(s+i,p,l);++i);printf("%s%s",s+i+l,p);write(1,s,i);}

Try it online!

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

SNOBOL4 (CSNOBOL4), 53 bytes

	P =INPUT
	INPUT ARB . R P REM . L
	OUTPUT =L P R
END

Try it online!

Takes input as Pivot, then Main, separated by a newline.

This is basically the SNOBOL equivalent of my R answer.

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

Perl 6, 31 bytes

->$_,$b {S/(.*?)$b(.*)/$1$b$0/}

Test it

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

PHP, 62 bytes

<?=![,$s,$p]=$argv,preg_filter("(^(.*)$p(.*)$)U","$2$p$1",$s);

requires PHP 7.1; may fail if the pivot contains regex special chars (\+*?[^]$(){}=!<>|:-).
no changes if Pivot is empty, empty output if Pivot is not in input.
Run with -n.

safe version, 77 bytes:

<?=preg_filter("(^(.*)".preg_quote($p=$argv[1])."(.*)$)U","$2$p$1",$argv[2]);

no changes if Pivot is empty, empty output if Pivot is not in input.
Run with -n.

non-regex version, 71 bytes:

$a=explode($p=$argv[2],$argv[1]);$a[]=array_shift($a);echo join($p,$a);

yields warnings if the Pivot is empty; no change if Pivot is not in input.

Run with -nr.

Try them online.

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

Red, 63 bytes

f: func[p s][rejoin[copy find/tail s p p copy/part s find s p]]

Try it online!

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

Swift, 131 bytes

import Foundation
func f(s:String,d:String){var c=s.components(separatedBy:d);print((c+[c[0]]).suffix(from:1).joined(separator:d))}

Explanation (ungolfed)

import Foundation                     // Import String.components
func f(s:String,d:String){
    var c=s.components(separatedBy:d) // Split the input string by the separator
    print((c+[c[0]])                  // Add the last element of c ([A,B,C] -> [A,B,C,A])
        .suffix(from:1)               // Remove the first element  ([A,B,C,A] -> [B,C,A])
        .joined(separator:d))         // Join with the separator
}
\$\endgroup\$
0
\$\begingroup\$

C (gcc), 76 bytes

f(s,t)char*s,*t;{char*p=strstr(s,t);printf("%s%s%.*s",p+strlen(t),t,p-s,s);}

Try it online!

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

C++11, 64 bytes

[s,p,&a]{int f=s.find(p);a=s.substr(f+p.size())+p+s.substr(0,f);}

A lambda, which captures the strings s, p and a, with a as a reference (in-out).

Test code

#include <iostream>
#include <string>

std::string Test(std::string s, std::string p) {
    std::string a;
[s,p,&a]{int f=s.find(p);a=s.substr(f+p.size())+p+s.substr(0,f);}();
    return a; 
}

int main() {
    std::string 
        s = "OneTwoThreeTwoOne",
        p = "Two",
        r = "ThreeTwoOneTwoOne";
    auto a = Test(s,p);
    std::cout << ((a==r)?"OK":"Failed") << ": " << a << std::endl; 

    return 0;
}
\$\endgroup\$
0
\$\begingroup\$

Clean, 83 bytes

import StdEnv;f s c=(\p=p takeWhile++[hd s,c:p dropWhile])\g=reverse(tl(g((<>)c)s))

A String in Clean is normally {#Char} - an unboxed (#) Char array ({}). This function takes [Char] instead of String, which is a second, valid version of String.

The full function signature is f :: [.t] .t -> [.t] | [.t <= Char].

Try it online!

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

Japt, 8 7 bytes

£Zg°Y}V

Try it here

\$\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.