12
\$\begingroup\$

In this challenge, you are required to shift characters in an inputted string n number of times and output the shifted string

Input

Input will first contain a string. In the next line, an integer, which denotes n will be present.

Output

  • If n is positive, shift the characters in the string to the right n times.
  • If n is negative, shift the characters in the string to the left n times.
  • If n is zero, don't shift the characters in the string.

After shifting (except when n is zero), print the shifted string.

Notes

  • The string will not be empty or null.
  • The string will not be longer than 100 characters and will only contain ASCII characters in range (space) to ~(tilde) (character codes 0x20 to 0x7E, inclusive). See ASCII table for reference.
  • The shift is cyclic.
  • The number n may be positive, negative, or zero.
  • n will always be greater than or equal to -1000 and lesser than or equal to 1000
  • You may take input via stdin or from command line arguments
  • The shifted string must be outputted in the stdout (or closest equivalent)
  • You may write a full program or a function which takes input and outputs the string in stdout or closest equivalent

Test Cases

1)

Hello world!
5             -->orld!Hello w

2)

Testing...
-3            -->ting...Tes

3)

~~~
1000          -->~~~

4)

12345
0             -->12345

5)

ABA
17            -->BAA

Scoring

This is , so the shortest submission (in bytes) wins.

\$\endgroup\$

16 Answers 16

5
\$\begingroup\$

Pyth, 4 bytes

.>zQ

This is almost similar to my CJam 5 byte version, except that Pyth as a auto-eval input operator Q.

.>              # Cyclic right shift of 
  z             # Input first line as string
   Q            # Rest of the input as evaluated integer

Try it online here

\$\endgroup\$
  • \$\begingroup\$ Exactly the same solution as this :-) \$\endgroup\$ – Spikatrix May 30 '15 at 9:07
  • \$\begingroup\$ @CoolGuy Its pretty straight forward. Though, I did not see this in sandbox.. \$\endgroup\$ – Optimizer May 30 '15 at 9:11
  • \$\begingroup\$ Seems to no longer work for some reason. Here's a working alternative, also 4 bytes. \$\endgroup\$ – hakr14 Aug 1 '18 at 18:53
3
\$\begingroup\$

Javascript (ES5), 55 52 bytes

p=prompt;with(p())p(slice(b=-p()%length)+slice(0,b))

Commented:

p = prompt; // store a copy of prompt function for reuse
with(p()) // extend scope chain with first input
    p( // print result
        slice(b = -p() % length) // take second input negated and modulo length
        +                        // and slice string by result
        slice(0, b) // concatenate with opposite slice
    )
\$\endgroup\$
2
\$\begingroup\$

CJam, 5 bytes

llim>

This is pretty straight forward.

l               e# Read the first line
 li             e# Read the second line and convert to integer
   m>           e# Shift rotate the first string by second integer places

Try it online here

\$\endgroup\$
  • 1
    \$\begingroup\$ Would this fall under built-in functions? \$\endgroup\$ – LegionMammal978 May 30 '15 at 18:12
  • \$\begingroup\$ @LegionMammal978 It is a built in function. But OP does not restrict the usage of built ins \$\endgroup\$ – Optimizer May 30 '15 at 18:22
  • 1
    \$\begingroup\$ Built-in functions are standard loopholes. \$\endgroup\$ – LegionMammal978 May 30 '15 at 18:37
  • 4
    \$\begingroup\$ @LegionMammal978 you point to an answer which has almost 50-50 up/down votes. That is not a community decision. \$\endgroup\$ – Optimizer May 30 '15 at 18:45
2
\$\begingroup\$

C, 93 bytes

main(a,v,n)char**v;{a=v[2]-v[1]-1;n=atoi(v[2]);a=a*(n>0)-n%a;printf("%s%.*s",v[1]+a,a,v[1]);}

More clear is the function-argument version that was modified to make the command line-argument version

f(s,n,c)char*s;{c=strlen(s);c=c*(n>0)-n%c;printf("%s%.*s",s+c,c,s);}

This one is only 68 bytes, which just goes to show how disadvantaged C is when dealing with command line arguments.

If the shift, n, is positive then strlen(s)-n%strlen(s) is the offset and if n is negative the offset is -n%strlen(s). The printf prints from the offset, c, to the end of the string, and then the final c characters from the beginning.

Examples:

$ ./rotstr "Hello world!" 5
orld!Hello w
$ ./rotstr "Testing..." -3
ting...Tes
$ ./rotstr "~~~" 1000
~~~
$ ./rotstr "12345" 0
12345
$ ./rotstr "ABA" 17
BAA
$ ./rotstr "Hello world!" -16
o world!Hell
\$\endgroup\$
  • \$\begingroup\$ It doesn't work as expected for me. When v[2] is "1", the code simply outputs the string without any modifications. And only "~~~" and "12345" works. The rest of them gives wrong outputs. If they all rotated one more time, it would have been correcet. \$\endgroup\$ – Spikatrix May 30 '15 at 11:50
  • \$\begingroup\$ I've tested it with both gcc and (with a slight modification main(a,v,n) -> n;main(a,v)) clang on linux and it works as expected. For gcc I'm using version 5.1.0 and compiling with gcc -o rotstr rotstr.c. What compiler are you using? \$\endgroup\$ – CL- May 30 '15 at 13:01
  • \$\begingroup\$ Tried making n global too. Same issue. I compiled using gcc file.c -o file. I'm using GCC 4.8.1 on windows. Is there any undefined behavior in your code? \$\endgroup\$ – Spikatrix May 30 '15 at 13:04
  • \$\begingroup\$ Replacing v[2]-v[1]-1 with strlen(v[1]) might make a difference, that's the only place I can think of something subtle going on. Unfortunately I don't have access to a windows machine to test. \$\endgroup\$ – CL- May 30 '15 at 13:15
  • \$\begingroup\$ Yes. The code worked when I changed that. \$\endgroup\$ – Spikatrix May 30 '15 at 13:16
2
\$\begingroup\$

Python 3, 45 bytes

s=input();n=int(input());print(s[-n:]+s[:-n])

The core of the program is

s[-n:]+s[:-n]

All the rest is just clumsy work with I/O.

\$\endgroup\$
  • 2
    \$\begingroup\$ This fail for the last ABA 17 test case, and would in general if |n| > length of string \$\endgroup\$ – Sp3000 May 30 '15 at 16:29
  • \$\begingroup\$ if you use n=int(input())%len(s);, it would work for integers greater than the string length, but require 7 more characters \$\endgroup\$ – JPMC May 30 '15 at 17:11
2
\$\begingroup\$

K, 8 7 bytes

{|x!|y}

There is already a primitive "rotate" (!) which performs a generalization of this operation for lists. K strings are lists of characters, so it applies. The spec favors CJam and Pyth a bit, though, because K's rotate happens to go the opposite direction of what is desired. Wrapping ! in a function and negating the implicit argument x will do what we want:

  f:{(-x)!y}
{(-x)!y}
  f[5;"Hello world!"]
"orld!Hello w"
  f[-3;"Testing..."]
"ting...Tes"
  f[17;"ABA"]
"BAA"

A slightly shorter approach, suggested by kirbyfan64sos, is to do away with the parentheses and negation in favor of reversing the string (|) before and after the rotation.

If it weren't for this impedance mismatch, the solution would be simply

!

Called identically:

  f:!
!
  f[5;"Hello, World!"]
", World!Hello"
  f[-5;"Hello, World!"]
"orld!Hello, W"
  f[0;"Hello, World!"]
"Hello, World!"
\$\endgroup\$
  • 1
    \$\begingroup\$ Would reversing the string with |, rotating that, and reversing it again yield the same result? If so, you can cut off a character. \$\endgroup\$ – kirbyfan64sos May 30 '15 at 22:24
  • \$\begingroup\$ Good point! That would work. \$\endgroup\$ – JohnE May 30 '15 at 23:01
1
\$\begingroup\$

Pip, 10 bytes

This could quite possibly be improved further. Still, for a language with no shift operator, 10 bytes ain't bad.

a@_M-b+,#a

Explanation:

            a, b are command-line args (implicit)
       ,#a  range(len(a))
    -b+     range(-b, len(a)-b)
a@_M        map(lambda x: a[x], range(-b, len(a)-b))
            Concatenate the list and print (implicit)

It works because string and list indexing in Pip is cyclical: "Hello"@9 == "Hello"@4 == "o".

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

rs, 180 chars

^(-\d+) (.*)/\1 \2\t
+^(-\d+) (.)(.*?)\t(.*)$/\1 \3\t\2\4
^(-\d+) \t/\1 
^(-?)(\d+)/\1 (_)^^(\2)
+_(_*) (.*)(.)$/\1 \3\2
^- /- \t
+^- (.*?)\t(.*?)(.)$/- \1\3\t\2
^-? +/
\t/

Live demo.

Most of this is reversing the string if the input number is negative. I took advantage of the fact that only some ASCII characters are valid input and used the tab to my advantage.

Note that I had to cheat a little: since rs is a single-line text modifier, I had to use <number> <text> as the input format.

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

Java, 167

enum S{;public static void main(String[]r){int n=-Integer.parseInt(r[1]),l=r[0].length();while(n<0)n+=l;n%=l;System.out.print(r[0].substring(n)+r[0].substring(0,n));}}

Takes the input through the command line.

funny enough, originally I had accidentally reversed how the string was supposed to be shifted. But fixing that mistake was shorter to just multiply n by -1 then to write the logic properly.

expanded:

enum Shift{
    ;
    public static void main(String[]args){
        int n=-Integer.parseInt(args[1]),length=args[0].length();
        while(n<0)n+=length;
        n%=length;
        System.out.print(args[0].substring(n)+args[0].substring(0,n));
    }
}
\$\endgroup\$
  • \$\begingroup\$ Why do you have enum S{; ... }? \$\endgroup\$ – Spikatrix Jun 2 '15 at 5:40
  • 1
    \$\begingroup\$ I opted to write the full program because 9 bytes wasn't really going to make a huge difference. Also it's a reminder when I look back to prefer enum S{;...} over class S{...} because (even though they take up the same number of bytes in this example) if I ever need to have an instance of the class, it takes one byte more with the enum version: enum S{X;...}. This helps if I want to declare a method or variable in the class without having to use the static keyword or explictly instantiating a new object of the class. \$\endgroup\$ – Jack Ammo Jun 3 '15 at 0:28
  • \$\begingroup\$ Wow! Nice. Never knew that enums can be used like this! \$\endgroup\$ – Spikatrix Jun 3 '15 at 5:49
  • \$\begingroup\$ I know it's been close to two years since you've posted this, but you can golf a few things. Integer.parseInt can be new Integer (-5 bytes); and n%=l; can be removed if you change r[0].substring(n)+ to r[0].substring(n%=l)+ (-2 bytes). Also, you might want to specify this is Java 6, because in Java 7 or higher an enum with main-method isn't possible anymore. \$\endgroup\$ – Kevin Cruijssen May 22 '17 at 7:29
  • \$\begingroup\$ too lazy to bother edit, but duely noted for the savings. \$\endgroup\$ – Jack Ammo May 28 '17 at 16:50
1
\$\begingroup\$

PHP>=7.1, 88 Bytes (Non-Competing)

for([,$s,$t]=$argv;$t;)$s=$t<0?substr($s,1).$s[!$t++]:$s[-1].substr($s,!$t--,-1);echo$s;

Testcases

\$\endgroup\$
  • \$\begingroup\$ Why 'non-competing'? \$\endgroup\$ – Spikatrix Jun 1 '17 at 9:39
  • \$\begingroup\$ @CoolGuy The PHP Version that is used is build after the question start \$\endgroup\$ – Jörg Hülsermann Jun 1 '17 at 9:45
1
\$\begingroup\$

Japt, 2 bytes

éV

Try it online

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

Casio Basic, 27 bytes

StrRotate s,s,-n:Print s

As it turns out, there's a built-in for this on the Casio ClassPad! But it works in reverse, hence -n.

24 bytes for the code, 3 bytes to specify s,n as arguments.

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

05AB1E, 6 bytes

DgI+FÁ

Try it online or verify all test cases.

Explanation:

D         # Duplicate the text input
 g        # Take it's length
          #  i.e. "Testing..." → 10
  I       # Take the integer input
   +      # Add them together
          #  i.e. 10 and -3 → 7
    F     # Loop that many times
     Á    #  And rotate once towards the right during every iteration

Since 05AB1E only has builtins for Rotate once towards the right/left, and not Rotate N amount towards the right/left, I loop length + input amount of times and rotate that many times towards the right.

For example:

  • "Testing..." and -3 will rotate 10 + -3 = 7 times towards the right, resulting in ting...Tes.
  • "Hello world" and 5 will rotate 11 + 5 = 16 times towards the right, resulting in worldHello.
\$\endgroup\$
0
\$\begingroup\$

Julia 0.6, 31 bytes

s|n=String(circshift([s...],n))

Try it online!

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

Stax, 2 bytes

|)

Run and debug it

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

Perl 5 + -palF, 26 bytes

$_=substr$_.$_,@F-<>%@F,@F

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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