22
\$\begingroup\$

Sandbox

A spin-off of a rip-off of a rip-off of a rip-off of a rip-off. Go upvote those!

Your task, if you accept it, is to write a program/function that outputs/returns its input/argument. The tricky part is that if I left shift your source code, the output must be left shifted too. Likewise, if I right shift your source code, the output must be right shifted too.

Source code will only be shifted once in each direction (in other words, only one shift will be applied, meaning that there are only three possible programs that need to be run). Consequently, the minimum source length should be 3.

Examples

Let's say your source code is ABC and the input is xyz. If I run ABC, the output must be xyz. But if I run BCA instead, the output must be yzx. And if I run CAB, the output must be zyx.

Let's say your source code is EFG and the input is Hello. If I run EFG, the output must be Hello. If I run GEF, the output must be oHell. And if I run FGE, the output must be elloH.

Let's say your source code is abcde and the input is 2019. If I run abcde, the output must be 2019. But if I run eabcd instead, the output must be 9201. And if I run bcdea, the output must be 0192.

Rules

  • The program must print the entire output shifted in the specified direction
  • Input can be taken in any convenient format.
  • Output can be in any convenient format as well.
  • Standard Loopholes are forbidden.
  • Source length should be at least 3 characters long, as to allow for unique shifted programs.

Scoring

This is code-golf so the answer with the fewest amount of bytes wins.

Leaderboards

Here is a Stack Snippet to generate both a regular leaderboard and an overview of winners by language.

To make sure that your answer shows up, please start your answer with a headline, using the following Markdown template:

# Language Name, N bytes

where N is the size of your submission. If you improve your score, you can keep old scores in the headline, by striking them through. For instance:

# Ruby, <s>104</s> <s>101</s> 96 bytes

If there you want to include multiple numbers in your header (e.g. because your score is the sum of two files or you want to list interpreter flag penalties separately), make sure that the actual score is the last number in the header:

# Perl, 43 + 2 (-p flag) = 45 bytes

You can also make the language name a link which will then show up in the leaderboard snippet:

# [><>](http://esolangs.org/wiki/Fish), 121 bytes

var QUESTION_ID=196864;
var OVERRIDE_USER=78850;
var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;function answersUrl(d){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+d+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(d,e){return"https://api.stackexchange.com/2.2/answers/"+e.join(";")+"/comments?page="+d+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(d){answers.push.apply(answers,d.items),answers_hash=[],answer_ids=[],d.items.forEach(function(e){e.comments=[];var f=+e.share_link.match(/\d+/);answer_ids.push(f),answers_hash[f]=e}),d.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(d){d.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),d.has_more?getComments():more_answers?getAnswers():process()}})}getAnswers();var SCORE_REG=function(){var d=String.raw`h\d`,e=String.raw`\-?\d+\.?\d*`,f=String.raw`[^\n<>]*`,g=String.raw`<s>${f}</s>|<strike>${f}</strike>|<del>${f}</del>`,h=String.raw`[^\n\d<>]*`,j=String.raw`<[^\n<>]+>`;return new RegExp(String.raw`<${d}>`+String.raw`\s*([^\n,]*[^\s,]),.*?`+String.raw`(${e})`+String.raw`(?=`+String.raw`${h}`+String.raw`(?:(?:${g}|${j})${h})*`+String.raw`</${d}>`+String.raw`)`)}(),OVERRIDE_REG=/^Override\s*header:\s*/i;function getAuthorName(d){return d.owner.display_name}function process(){var d=[];answers.forEach(function(n){var o=n.body;n.comments.forEach(function(q){OVERRIDE_REG.test(q.body)&&(o="<h1>"+q.body.replace(OVERRIDE_REG,"")+"</h1>")});var p=o.match(SCORE_REG);p&&d.push({user:getAuthorName(n),size:+p[2],language:p[1],link:n.share_link})}),d.sort(function(n,o){var p=n.size,q=o.size;return p-q});var e={},f=1,g=null,h=1;d.forEach(function(n){n.size!=g&&(h=f),g=n.size,++f;var o=jQuery("#answer-template").html();o=o.replace("{{PLACE}}",h+".").replace("{{NAME}}",n.user).replace("{{LANGUAGE}}",n.language).replace("{{SIZE}}",n.size).replace("{{LINK}}",n.link),o=jQuery(o),jQuery("#answers").append(o);var p=n.language;p=jQuery("<i>"+n.language+"</i>").text().toLowerCase(),e[p]=e[p]||{lang:n.language,user:n.user,size:n.size,link:n.link,uniq:p}});var j=[];for(var k in e)e.hasOwnProperty(k)&&j.push(e[k]);j.sort(function(n,o){return n.uniq>o.uniq?1:n.uniq<o.uniq?-1:0});for(var l=0;l<j.length;++l){var m=jQuery("#language-template").html(),k=j[l];m=m.replace("{{LANGUAGE}}",k.lang).replace("{{NAME}}",k.user).replace("{{SIZE}}",k.size).replace("{{LINK}}",k.link),m=jQuery(m),jQuery("#languages").append(m)}}
body{text-align:left!important}#answer-list{padding:10px;float:left}#language-list{padding:10px;float:left}table thead{font-weight:700}table td{padding:5px}
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="https://cdn.sstatic.net/Sites/codegolf/primary.css?v=f52df912b654"> <div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td><a href="{{LINK}}">{{SIZE}}</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td><a href="{{LINK}}">{{SIZE}}</a></td></tr></tbody> </table> 

\$\endgroup\$
  • \$\begingroup\$ Is I/O flexible? May input and output be a vector of characters? \$\endgroup\$ – Robin Ryder Dec 10 '19 at 20:50
  • \$\begingroup\$ @RobinRyder updated the question to allow flexible IO \$\endgroup\$ – Lyxal Dec 10 '19 at 20:53
  • \$\begingroup\$ Is trailing whitespace acceptable? \$\endgroup\$ – frank Dec 10 '19 at 21:08
  • \$\begingroup\$ Trailing and leading whitespace are both acceptable. \$\endgroup\$ – Lyxal Dec 10 '19 at 21:09
  • 6
    \$\begingroup\$ How is the empty string shifted? Does it even have to be handled? \$\endgroup\$ – Post Rock Garf Hunter Dec 10 '19 at 21:17

19 Answers 19

24
\$\begingroup\$

Haskell, 51 bytes

midm(a:b)=b++[a]
i=(:).last<*>init
main=interact id

Try it online!

Explanation

Our main function is just interact of a another function. By default it is id which just returns the input, but if we shift we either add an m to make idm or remove the d to make i. Both of which we have defined to be roll left and roll right.

\$\endgroup\$
  • \$\begingroup\$ Right shift doesnt seem to work? Might just be tio \$\endgroup\$ – frank Dec 10 '19 at 21:36
  • \$\begingroup\$ @frank That looks like it is working, the last character there is a newline which is being shifted to the front. \$\endgroup\$ – Post Rock Garf Hunter Dec 10 '19 at 21:37
  • \$\begingroup\$ Oh I see, didnt notice the newline haha \$\endgroup\$ – frank Dec 10 '19 at 21:38
16
\$\begingroup\$

05AB1E, 4 bytes

À\Á\

Try it online
ry it shifted towards the leftT
tTry it shifted towards the righ

Explanation:

À     # Shift the (implicit) input once towards the left
 \    # Discard it from the stack
  Á   # Shift the (implicit) input once towards the right
   \  # Discard it from the stack
      # (output the implicit input implicitly as result)

\     # Discard (no-op, since the stack is already empty)
 À    # Shift the (implicit) input once towards the left
  \   # Discard it from the stack
   Á  # Shift the (implicit) input once towards the right
      # (and output this right-shifted input at the top of the stack implicitly as result)

\     # Discard (no-op, since the stack is already empty)
 Á    # Shift the (implicit) input once towards the right
  \   # Discard it from the stack
   À  # Shift the (implicit) input once towards the left
      # (and output this left-shifted input at the top of the stack implicitly as result)
\$\endgroup\$
11
\$\begingroup\$

R, 82 75 67 62 bytes

-4 bytes thanks to Giuseppe.

!-1->i
c(tail(s<-el(strsplit(scan(,""),"")),1/i),head(s,-i))#!

Try it online!

ry it online!T

!Try it online

Uses rightwards assignment -> (this is only the 2nd time I have ever used rightwards assignment). The value of i is either 0, 1 or -1 depending on the shift. This is used to give the correct output:

  • when i=1, tail(s, 1) gives the last element and head(s, -1) gives all elements but the last
  • when i=-1, tail(s, -1) gives all elements but the first and head(s, 1) gives the first element
  • when i=0, tail(s, Inf) gives s and head(s, 0) gives the empty vector.
\$\endgroup\$
  • 1
    \$\begingroup\$ I think your first head(s,1) should be head(s,-1), but this is yet another rocking good answer with the ->. \$\endgroup\$ – Giuseppe Dec 12 '19 at 17:54
  • \$\begingroup\$ @Giuseppe You are right about the typo in the explanation, thanks! \$\endgroup\$ – Robin Ryder Dec 12 '19 at 19:45
  • \$\begingroup\$ OK, I think this should work for 63 bytes: Try it online! \$\endgroup\$ – Giuseppe Dec 13 '19 at 18:16
  • 1
    \$\begingroup\$ @Giuseppe Thanks! I'd been trying things along those lines, but couldn't get it right. I got it down to 62 from your version. \$\endgroup\$ – Robin Ryder Dec 13 '19 at 20:39
9
\$\begingroup\$

Pyth, 18 bytes

?.<Q1 Q ;*.>Q1qk" 

Try it online!, Right-shift, Left-shift

Pretty proud of this one. Has a trailing newline except on right shift. Makes use of the fact that a space before a pyth expression suppresses the output. Note the last byte is a space.

How it works

?.<Q1 Q ;*.>Q1qk" - Unshifted
?.<Q1                - If the input left-shifted is truthy
      Q ;            - Print the input, end if statement
         *.>Q1       - Right shifted input, multiplied by...
              qk"    - whether k (an empty string) is equal to the string at the end.                   
                       Since there is a space at the end, y(Q) is multiplied by zero.

.<Q1 Q ;*.>Q1qk" ? - Left Shifted
.<Q1               - Left shift the input and print it.
     Q             - This input is preceded by a space and as such does not print
               " ? - Obviously is not equal to an empty string (Pyth 
                     closes strings implicitly)

 ?.<Q1 Q ;*.>Q1qk" - Right Shifted
 ?.<Q1 Q ;         - The space before the if statement suppresses the printing
                 " - Since the space has been removed from the end, the 
                     terminating string is now an empty string, and y(Q) is printed
\$\endgroup\$
8
\$\begingroup\$

JavaScript (Browsers), 81 68 66 bytes

xx=1;var x,xxx;w=prompt();alert(w.slice(a=x|-xxx)+w.slice(0,a))//x

Original solution (81 bytes)

tob=-1;try{ob;atob=1}catch(e){}w=prompt();alert(w.slice(atob)+w.slice(0,atob))//a

No TIO link because it works only in browsers with atob function defined. In order to show the output in a more friendly way, prompt and alert are overridden in the screenshot below.

enter image description here

Explanation

The declarations of x and xxx are hoisted to the beginning automatically, so the declarations won't clear the values assigned beforehand.

No rotation

xx=1;var x,xxx;w=prompt();alert(w.slice(a=x|-xxx)+w.slice(0,a))//x

// xx = 1, so a = 0, so we have alert(w.slice(0)+w.slice(0,0))

Left rotation

x=1;var x,xxx;w=prompt();alert(w.slice(a=x|-xxx)+w.slice(0,a))//xx

// x = 1, so a = 1, so we have alert(w.slice(1)+w.slice(0,1))

Right rotation

xxx=1;var x,xxx;w=prompt();alert(w.slice(a=x|-xxx)+w.slice(0,a))//

// xxx = 1, so a = -1, so we have alert(w.slice(-1)+w.slice(0,-1))
\$\endgroup\$
6
\$\begingroup\$

APL (Dyalog Unicode), 15 11 bytesSBCS

-4 thanks to inspiration from Luis Mendo's solution.

Full program, prompting for input via stdin.


1⊢⍞⌽⍨¯2+≢1⍬

Try it online!

1⍬ the list [1,[]]

 tally the elements in that; 2

¯2+ add negative two to that; 0

⌽⍨ cyclically rotate the following by that number of steps:

 stdin

1⊢ yield that, ignoring the 1


⊢⍞⌽⍨¯2+≢1⍬1

ry it online!T

1⍬1 the list [1,[],1]

 tally the elements in that; 3

¯2+ add negative two to that; 1

⌽⍨ cyclically rotate the following by that number of steps:

 stdin

 yield that


⍬1⊢⍞⌽⍨¯2+≢1

!Try it online

1 the number 1

 tally the elements in that; 1

¯2+ add negative two to that; -1

⌽⍨ cyclically rotate the following by that number of steps:

 stdin

⍬1⊢ yield that, ignoring the list [[],1]

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

Japt, 4 bytes

ÉUé0

Try it


0ÉUé

Ué0É


Works with arrays too.

ÉUé0

Ué0É

0ÉUé

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

Python 2, 64 bytes

bc=k=input()
print[k,k[1:]+k[0],k,k[-1]+k[:-1]][len(dir()[5])]#a

Try it online!, !Try it online and ry it online!T

dir is a builtin function that returns a list of all variable names. The length of the first variable name is used to choose the right output.

\$\endgroup\$
  • \$\begingroup\$ I think print k[2-len(dir()[5]):]+k[:2-len(dir()[5])] saves 4 bytes and then there's a further obvious 10-byte saving. \$\endgroup\$ – Neil Dec 11 '19 at 11:33
3
\$\begingroup\$

MATL, 9 8 bytes

TFsqYS%T

Try it online! See also right-shifted and left-shifted versions.

How it works

Normal version:

TF    % Push array [true, false]
sq    % Sum; subtract 1. Gives 0
YS    % Implicit input. Circular shift by that amount. Implicit display
%T    % Comment. Ignore rest of line

Right-shifted version:

TTF   % Push array [true, true, false]
sq    % Sum; subtract 1. Gives 1
YS    % Implicit input. Circular shift by that amount. Implicit display
%     % Comment. Ignore rest of line

Left-shifted version:

F     % Push array [false]
sq    % Sum; subtract 1. Gives -1
YS    % Implicit input. Circular shift by that amount. Implicit display
%TT   % Comment. Ignore rest of line
\$\endgroup\$
3
\$\begingroup\$

Runic Enchantments, 7 bytes

@{͍{͍

Try it online!

Input is limited to a single string (spaces need to be escaped).

This is the best I can come up with. It is not a full program, but instead a function (see the header on TIO for the entry, stdin handling, and Branch).

This also relies on treating each cell of the function as a single object.

Alternatively this works on space separated inputs and doesn't require modifier characters, but outputs them all with no separator.

Without those concessions, the challenge would be impossible in Runic, due to having explicit input and output, as well as a termination command (eg. sample program i@}, if it was rotated two to the right to @}i, the program would terminate without reading or outputting anything; with an explicit entry point, the program could not distinguish its own rotation).

\$\endgroup\$
  • \$\begingroup\$ If I shift it to {@{͍ the output stays xyz? I don't know the language, maybe my fault. \$\endgroup\$ – findusl Dec 11 '19 at 15:51
  • \$\begingroup\$ @findusl That's what I meant by treating each cell as a rotation, rather than unicode code points (you accidentally'd one of the ͍). You're looking for this. This is because { rotates's the IP's stack, but rotates the string on the top of the stack. \$\endgroup\$ – Draco18s no longer trusts SE Dec 11 '19 at 16:12
3
\$\begingroup\$

C (gcc), 109 86 83 bytes

-20 bytes thanks to xibu

Takes the text to display is a command line argument. The active code is bookended by newlines, having the result of changing what __LINE__ evaluates to when shifting the code. This means 2-__LINE__ will be +1 for shifting left, 0 for no shift, and -1 for shifting right.

No shift


K;main(L,s)char**s;{for(L=strlen(s[1]);K<L;)putchar(s[1][(K+++2-__LINE__+L)%L]);}

Try it online!

Left shift

K;main(L,s)char**s;{for(L=strlen(s[1]);K<L;)putchar(s[1][(K+++2-__LINE__+L)%L]);}


Try it online!

Right shift



K;main(L,s)char**s;{for(L=strlen(s[1]);K<L;)putchar(s[1][(K+++2-__LINE__+L)%L]);}

Try it online!

\$\endgroup\$
  • \$\begingroup\$ You can shorten the console print of your function by 20 bytes I,L,K;main(S,s)char**s;{K=L=strlen(s[1]);for(I=2-__LINE__+L;K--;)putchar(s[1][I++%L]);} \$\endgroup\$ – xibu Dec 12 '19 at 20:28
  • \$\begingroup\$ @xibu Nice one! \$\endgroup\$ – gastropner Dec 12 '19 at 21:54
3
\$\begingroup\$

C (gcc), 96 94 bytes

-2 bytes thanks to gastropner

BC=1;C;ABC;S,K;main(N,c)char**c;{K=S=strlen(c[1]);for(N=C-ABC+S;K--;)putchar(c[1][N++%S]);}//A

Try it online!

explanation:

BC=1;       // declare and set variable ABC, BC or C (depending on shift)
C;ABC;      // declare possible variable names
            // existing variables are not changed, newly declared variables are set to 0

int main(int NumArgs,char** c)
{
    char* input = c[1];

    int S = strlen(input);      // string length used for modulo
    int K = S;                  // string length used to count characters
    int I = C - ABC + S;        // set start of output

    for(;K--;)                  // display K characters
        putchar(input[I++%S]);  // display character and move read position
}
//A                             // A used to create valid variable name in first line
\$\endgroup\$
  • 1
    \$\begingroup\$ Elegant! You can shave another 2 bytes off by using N instead of I: BC=1;C;ABC;S,K;main(N,c)char**c;{K=S=strlen(c[1]);for(N=C-ABC+S;K--;)putchar(c[1][N++%S]);}//A \$\endgroup\$ – gastropner Dec 12 '19 at 22:10
2
\$\begingroup\$

Ruby, 72 bytes

aa,a,aaa,g=0,-1,1,gets
f=->s,a{(g*3)[s+a..-s+a-1]}
puts f.call g.size,aa

Try it online!

a,a,aaa,g=0,-1,1,gets
f=->s,a{(g*3)[s+a..-s+a-1]}
puts f.call g.size,aaa

Try it online!

aaa,a,aaa,g=0,-1,1,gets
f=->s,a{(g*3)[s+a..-s+a-1]}
puts f.call g.size,a

Try it online!

Triplicates the input then takes a middle substring, shifted according to whether the source code was shifted. Doesn't take kindly to empty input, unfortunately.

Ruby actually has a built-in rotate function, there might be a way to use this but it only works on arrays and not strings.

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

Charcoal, 8 bytes

←→Fθ§θⅈ←

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

←           Move cursor left (decrement X-position)
 →          Move cursor right (increment X-position)
  F         For each character of
   θ        Input string
    §       Implicitly print cyclically indexed character
     θ      Input string
      ⅈ     Current X-position
       ←    Move cursor left (no-op)

Rotating the code simply causes the X-position to start at 1 or -1 appropriately thus causing the characters of string to be output cyclically offset, however Charcoal does not include the cursor movement in the output.

→Fθ§θⅈ←←

ry it online!T Link is to verbose version of code.

←←→Fθ§θⅈ

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

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

Wolfram Language (Mathematica), 33 bytes

0+#~RotateLeft~Log10[.1$]&/.$->10

Try it online!

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

Jelly, 9 bytes

10%3Cṙ@ḷ4

Try it online!

A monadic link taking a Jelly string and returning the processed Jelly string.

All three variations

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

Perl 5 -p, 37 bytes

's/(.)(.*)/\2\1/;';";s/(.*)(.)/\2\1/"

Try it online!

Left shift

s/(.)(.*)/\2\1/;';";s/(.*)(.)/\2\1/"'

Try it online!

Right shift

"'s/(.)(.*)/\2\1/;';";s/(.*)(.)/\2\1/

Try it online!

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

Attache, 12 bytes

0&~Rotate??~

Try it online!

Returns a function.

Explanation

Rotate is a function which does string rotation. ~Rotate reverses the argument order. x& binds the x to the left argument of the given function. ??~ is a comment (?? marking the start of it). So, this returns a function which, given y, returns Rotate[y, x]—rotating y by x degree.

For the case of no rotation, this rotates the string by 0.

When rotated once right, this becomes:

~0&~Rotate??

Which is the same as the above, except this time it's Rotate[y, -1], which performs the desired transformation.

If instead we rotate left once, it becomes:

&~Rotate??~0

&, when used in a unary context such as this, will, if given an array as input, apply the each element of the array as an argument for the function. However, the argument is a string, and this is effectively a no-op. Thus, Rotate[y, x] has no right argument; by default, it is 1, so this performs the desired transformation.

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

Crystal, 52 bytes

Unshifted

25.tap{|n|puts gets.to_s.chars.rotate(n%3-1).join}#2

Try it online!

Left-Shifted

5.tap{|n|puts gets.to_s.chars.rotate(n%3-1).join}#22

Try it online!

Right-Shifted

225.tap{|n|puts gets.to_s.chars.rotate(n%3-1).join}#

Try it online!

Crystal's Object#tap passes the object into the following block. Then we get the input, guarantee it's a string, get an array of that string's characters, and then rotate. We rotate by the number at the beginning, modded by three and then subtracted by 1 (with the number at the beginning "chosen" based on convenient modulo properties).

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