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 rightn
times. - If
n
is negative, shift the characters in the string to the leftn
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 code-golf, so the shortest submission (in bytes) wins.
26 Answers 26
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
-
-
\$\begingroup\$ @CoolGuy Its pretty straight forward. Though, I did not see this in sandbox.. \$\endgroup\$Optimizer– Optimizer2015年05月30日 09:11:28 +00:00Commented May 30, 2015 at 9:11
-
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
)
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
-
1\$\begingroup\$ Would this fall under built-in functions? \$\endgroup\$LegionMammal978– LegionMammal9782015年05月30日 18:12:45 +00:00Commented May 30, 2015 at 18:12
-
\$\begingroup\$ @LegionMammal978 It is a built in function. But OP does not restrict the usage of built ins \$\endgroup\$Optimizer– Optimizer2015年05月30日 18:22:55 +00:00Commented May 30, 2015 at 18:22
-
1\$\begingroup\$ Built-in functions are standard loopholes. \$\endgroup\$LegionMammal978– LegionMammal9782015年05月30日 18:37:44 +00:00Commented May 30, 2015 at 18:37
-
5\$\begingroup\$ @LegionMammal978 you point to an answer which has almost 50-50 up/down votes. That is not a community decision. \$\endgroup\$Optimizer– Optimizer2015年05月30日 18:45:50 +00:00Commented May 30, 2015 at 18:45
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
-
\$\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– Spikatrix2015年05月30日 11:50:08 +00:00Commented May 30, 2015 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 withgcc -o rotstr rotstr.c
. What compiler are you using? \$\endgroup\$CL-– CL-2015年05月30日 13:01:47 +00:00Commented May 30, 2015 at 13:01 -
\$\begingroup\$ Tried making
n
global too. Same issue. I compiled usinggcc file.c -o file
. I'm using GCC 4.8.1 on windows. Is there any undefined behavior in your code? \$\endgroup\$Spikatrix– Spikatrix2015年05月30日 13:04:58 +00:00Commented May 30, 2015 at 13:04 -
\$\begingroup\$ Replacing
v[2]-v[1]-1
withstrlen(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-– CL-2015年05月30日 13:15:31 +00:00Commented May 30, 2015 at 13:15 -
\$\begingroup\$ Yes. The code worked when I changed that. \$\endgroup\$Spikatrix– Spikatrix2015年05月30日 13:16:13 +00:00Commented May 30, 2015 at 13:16
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.
-
2\$\begingroup\$ This fail for the last
ABA 17
test case, and would in general if|n| > length of string
\$\endgroup\$Sp3000– Sp30002015年05月30日 16:29:27 +00:00Commented May 30, 2015 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– JPMC2015年05月30日 17:11:07 +00:00Commented May 30, 2015 at 17:11
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!"
-
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– kirbyfan64sos2015年05月30日 22:24:08 +00:00Commented May 30, 2015 at 22:24 -
\$\begingroup\$ Good point! That would work. \$\endgroup\$JohnE– JohnE2015年05月30日 23:01:22 +00:00Commented May 30, 2015 at 23:01
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.
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"
.
rs, 180 chars
^(-\d+) (.*)/1円 2円\t
+^(-\d+) (.)(.*?)\t(.*)$/1円 3円\t2円4円
^(-\d+) \t/1円
^(-?)(\d+)/1円 (_)^^(2円)
+_(_*) (.*)(.)$/1円 3円2円
^- /- \t
+^- (.*?)\t(.*?)(.)$/- 1円3円\t2円
^-? +/
\t/
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.
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));
}
}
-
\$\begingroup\$ Why do you have
enum S{; ... }
? \$\endgroup\$Spikatrix– Spikatrix2015年06月02日 05:40:36 +00:00Commented Jun 2, 2015 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– Jack Ammo2015年06月03日 00:28:08 +00:00Commented Jun 3, 2015 at 0:28
-
\$\begingroup\$ Wow! Nice. Never knew that
enum
s can be used like this! \$\endgroup\$Spikatrix– Spikatrix2015年06月03日 05:49:07 +00:00Commented Jun 3, 2015 at 5:49 -
1\$\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 benew Integer
(-5 bytes); andn%=l;
can be removed if you changer[0].substring(n)+
tor[0].substring(n%=l)+
(-2 bytes). Also, you might want to specify this is Java 6, because in Java 7 or higher an enum withmain
-method isn't possible anymore. \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2017年05月22日 07:29:41 +00:00Commented May 22, 2017 at 7:29 -
\$\begingroup\$ too lazy to bother edit, but duely noted for the savings. \$\endgroup\$Jack Ammo– Jack Ammo2017年05月28日 16:50:51 +00:00Commented May 28, 2017 at 16:50
PHP>=7.1, 88 Bytes
for([,$s,$t]=$argv;$t;)$s=$t<0?substr($s,1).$s[!$t++]:$s[-1].substr($s,!$t--,-1);echo$s;
Pascal (ISO standard 10206, "Extended Pascal"), 120 Bytes
program p(input,output);var s:string(100);n:integer;begin read(s,n);n:=(-n)mod length(s);writeLn(subStr(s,n+1),s:n)end.
Ungolfed:
program shiftCharactersInAString(input, output);
var
line: string(100);
n: integer;
begin
read(line, n);
{ In Pascal, the result of the `mod` operation is non-negative. }
n := (-n) mod length(line);
{ In Pascal, string indices are 1‐based. }
writeLn(subStr(line, n + 1), line:n)
{ `line:n` is equivalent to `subStr(line, 1, n)` (if `n` ≤ `length(line)`). }
end.
05AB1E, (削除) 6 (削除ここまで) (削除) 5 (削除ここまで) 3 bytes
(._
Inputs in the order integer,string
.
Try it online or verify all test cases.
Explanation:
( # Negate the first (implicit) input-integer
._ # Rotate the second (implicit) input-string that many times towards the left
# (which supports negative integers as rotating right instead)
# (after which the result is output implicitly)
05AB1E (legacy), (削除) 6 (削除ここまで) 5 bytes
sg+FÁ
Inputs in the order integer,string
.
Try it online or verify all test cases.
Explanation:
s # Swap so the two (implicit) inputs are in reversed order on the stack
g # Pop and push the length of the top input-string
+ # Add it to the input-integer
F # Loop that many times
Á # And rotate once towards the right during every iteration
# (using the last implicit input-string in the first iteration)
Since the legacy version of 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 inting...Tes
."Hello world"
and5
will rotate \11ドル + 5 = 16\$ times towards the right, resulting inworldHello
.
The new version of 05AB1E does have a builtin for rotating \$n\$ amount of times towards the left, which is ._
, saving 2 bytes.
Wolfram Language (Mathematica), 40 bytes
StringJoin@RotateRight[Characters@#,#2]&
StringJoin@RotateLeft[Characters@#,-#2]&
Vyxal, 1 byte
ǔ
Takes the number then the string. Prepend $
if you want the inputs the other way round.
Built-in solution for "rotate right". Rotation is modular so we don't have to worry about negative inputs.
Thunno J
, \$ 8 \log_{256}(96) \approx \$ 6.58 bytes
LR_z0sAI
No shift operator in Thunno so we have to do it ourselves.
Explanation
LR_z0sAI # Implicit input STACK: "Hello, World!", 5
LR # Length range STACK: 5, [0..12]
_ # Swapped subtract STACK: [-5..7]
z0 # First input STACK: [-5..7], "Hello, World!"
sAI # Swap and index STACK: ['o', 'r', 'l', 'd', '!', 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W']
# J flag joins STACK: "orld!Hello, W"
# Implicit output
HP‐41C series, 4 Bytes
Input string is located in alpha register and number to rotate on top of the stack (i. e. the X register). An extended functions module or HP‐41CX is required.
CHS 1 Byte flip sign because AROT acts just the opposite as required
AROT 2 Bytes rotate alpha register according to value in X register
AVIEW 1 Byte display contents of alpha register