55
\$\begingroup\$

Here is a relatively simple challenge for you.

Given a string of length N, output the string forwards, then backwards, then forwards, then backwards... etc. N times. For example, if your input was

Hello!

You should output:

Hello!!olleHHello!!olleHHello!!olleH

You may also optionally output one trailing newline.

Your submission may be either a full program or a function, and you may take input and output in any reasonable format. For example, you may take IO from STDIN/STDOUT, function arguments and return value, from a file, etc. You can safely assume that the input string will not be empty, and will only contain printable ASCII. You must output the new string on a single line. So, for example, if the output to the last example was

Hello!
!olleH
Hello!
!olleH
Hello!
!olleH

This would not be a valid solution!

Here are some more test cases:

Input:
a
Output:
a

Input:
abcd
Output:
abcddcbaabcddcba

Input:
OK!
Output:
OK!!KOOK!

Input:
4815162342
Output:
4815162342243261518448151623422432615184481516234224326151844815162342243261518448151623422432615184

Input:
PPCG
Output:
PPCGGCPPPPCGGCPP

Input:
42
Output:
4224

Leaderboards

Since this is a challenge, standard loopholes are banned, and the shortest answer in bytes wins! However, this is also a competition to have the shortest answer in any particular langauge. While it's unlikely that a Java answer will beat an answer in perl, or some golfing language, it's still very impressive to have the shortest Java answer. So, you can use this leaderboard to see both

  1. The shortest answer out of all languages, and

  2. The shortest answer in each individual 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=93261,OVERRIDE_USER=31716;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&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(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.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(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;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="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <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><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><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>

\$\endgroup\$
9
  • \$\begingroup\$ In your example, shouldn't that be olleH, not elloH ? \$\endgroup\$
    – Arnaud
    Commented Sep 15, 2016 at 3:27
  • 2
    \$\begingroup\$ @Downgoat No, you must take input and output in the same format as the spec describes. \$\endgroup\$
    – DJMcMayhem
    Commented Sep 15, 2016 at 4:15
  • 4
    \$\begingroup\$ Shouldn't the title be StringgnirtSStringgnirtSStringgnirtS? \$\endgroup\$
    – Luis Mendo
    Commented Sep 15, 2016 at 8:39
  • 2
    \$\begingroup\$ @carusocomputing It won't: "You can safely assume that the input string will not be empty, and will only contain printable ASCII." \$\endgroup\$ Commented Sep 15, 2016 at 13:50
  • 1
    \$\begingroup\$ en.wikipedia.org/wiki/ASCII#Printable_characters Ah, didn't know that was a well defined subset of ASCII. I imagined printable to include \t, \n, etc... \$\endgroup\$ Commented Sep 15, 2016 at 14:59

106 Answers 106

25
\$\begingroup\$

Vim, 39, 34 keystrokes

:se ri
Y:s/./<C-r>"/g
<C-o>qqgJC<C-r>"<esc>gJ@qq@q

5 bytes saved thanks to @Lynn!

Here is a gif of it happening live: (Note that this gif is of a previous version since I haven't had time to re-record it yet).

enter image description here

And here is an explanation of how it works:

:se ri                  "Turn 'reverse indent' on.
Y                       "Yank this line
:s/./<C-r>"/g           "Replace every character on this line with the register
                        "We just yanked followed by a newline
<C-o>                   "Jump to our previous location
     qq                 "Start recording in register 'q'
       gJ               "Join these two lines
         C              "Delete this line, and enter insert mode
          <C-r>"<esc>   "Paste the line we just deleted backwards 
gJ                      "Join these two lines
  @q                    "Call macro 'q'. This will run until we hit the bottom of the buffer.
    q                   "Stop recording.
     @q                 "Start our recursive macro

On a side note, Y grabs an extra newline, which is usually an obnoxious feature. This is probably the first ever time that it has actually saved several bytes!

\$\endgroup\$
8
  • 2
    \$\begingroup\$ Instead of :%s/\n<cr>, you can do v{gJ to save three bytes. \$\endgroup\$
    – lynn
    Commented Sep 15, 2016 at 8:45
  • 2
    \$\begingroup\$ A VIM answer?! That's a classy move on your part. \$\endgroup\$ Commented Sep 15, 2016 at 12:31
  • \$\begingroup\$ @Lynn Thanks for the tip! I ended up doing something slightly different and took 5 off instead. \$\endgroup\$
    – DJMcMayhem
    Commented Sep 15, 2016 at 20:10
  • \$\begingroup\$ This assumes that @q is empty at the start, right? or the @q before stopping recording would do something arbitrary. (This leads me to my favorite vim trivium that I've come up with: everyone knows that quitting vim is as easy as :q<CR>, but how do you close and save all your files? easy: just qqqqqZZ@qq@q!) \$\endgroup\$
    – wchargin
    Commented Sep 17, 2016 at 23:24
  • \$\begingroup\$ @wchargin Yes, this does require @q to be empty. Why not just do :wqa instead? Also wanna know how to generate a fractal in vim? qqqqq<C-w>v<C-w>n@qq@q :D \$\endgroup\$
    – DJMcMayhem
    Commented Sep 17, 2016 at 23:43
22
\$\begingroup\$

Python, 40 bytes

f=lambda s,i=0:s[i:]and s+f(s[::-1],i+1)

A recursive function. Prepends the input string s to the function of the reverse until the counter i exceed the length of s.

\$\endgroup\$
4
  • \$\begingroup\$ Wow. I was just about to submit a 56 byte python answer, haha \$\endgroup\$
    – DJMcMayhem
    Commented Sep 15, 2016 at 3:15
  • \$\begingroup\$ @DJMcMayhem it also beats lambda s:(len(s)*(s+s[::-1]))[:len(s)**2] by one byte. \$\endgroup\$ Commented Sep 15, 2016 at 6:01
  • \$\begingroup\$ I've gotten this f = lambda s : ''.join([s[((-1)**(i//len(s)) <= 0)*(len(s)-1)+(-1)**(i//len(s))*(i%len(s))] for i in range(len(s)*len(s))]) but it's 136 bytes according to sys.sizeof, interestingly it's the same size as f = lambda s : ''.join([s[::1] if i%2 else s for i in range(len(s))]) \$\endgroup\$
    – Carel
    Commented Sep 18, 2016 at 19:39
  • \$\begingroup\$ @JonathanAllan not in python 3.8+ with the walrus operator : lambda s:((l:=len(s))*(s+s[::-1]))[:l*l] (also 40 bytes) \$\endgroup\$
    – Jakque
    Commented Jun 16, 2021 at 14:58
17
\$\begingroup\$

Brain-Flak, 418 378 228 bytes

This is my Brain-Flak masterpiece. It may not be well golfed but the challenge is the most difficult I have ever encountered.

Try it online!

(([])[()]){({}[()]<(({}(<()>))<{({}[()]<(({}()<(({}<>))>)<({()<({}[()]<({}<({}<>)<>>)>)>}{}<>){({}[()]<({}<>)<>>)}{}>)>)}{}{}<>([]){{}({}<>)<>([])}{}<>>)>)}{}([(({}))]{({})({}[()])}{}){(({}[({}<>)<>])<<>({}<><{(({}[()])<{({}[()]<({}<({}<>)<>>)>)}{}<>([]){{}({}<>)<>([])}{}<>>)}{}>)>)}

Explanation

This explanation is now a bit outdated but it still does a pretty good job of explaining the program.

This explanation is going to go a little different from my regular explanation process. I am going to explain how I came about this result rather than explain the result in order. Here it goes:

Roller

After working at the problem a quite a bit I came up with this code:

(n[()])({()<({}[()]<({}<({}<>)<>>)>)>}{}<>){({}[()]<({}<>)<>>)}{}<>

This code (where n is the literal for some number. e.g. ()()) will take the item on the top of the stack and move it down n steps. With n as the stack height this will perform a stack "roll". i.e. move the top item to the bottom of the stack. Here's how it works:

We put the place we want to move the item to minus one on the stack. Why minus one? I don't know it just works that way.

(n[()])

We then loop until this number reaches zero keeping track of the loop with a ().

{()<({}[()]<...>)>)>}{}

Each time we loop we pick up the top item and move the item underneath it to the other stack. This puts the number on top in its place.

({}<({}<>)<>>)

All we need to do now is put the numbers we moved back. We switch to the off stack and push the number of runs the loop made.

(...<>)

We loop decrementing the newly pushed number until it reaches zero. Each time we move one number back.

{({}[()]<({}<>)<>>)}{}<>

Reverse

I next modified the roll to make a full stack reverse:

(n){(({}[()])<{({}[()]<({}<({}<>)<>>)>)}{}<>([]){{}({}<>)<>([])}{}<>>)}{}

Once again n represents the depth of the reverse. That is the top n items on the stack will be reversed. How it works:

The reverse is just a fancily wrapped roller. We simply roll the top of the stack n times decrementing the depth of the roll by one each time.

(n){(({}[()])<ROLLER>)}{}

Duplicate

In place duplication is hard. Really hard. After I figured out how to reverse the stack it still took a great deal of effort to come up with the duplication algorithm.

Here it is:

(((n)<{({}[()]<(({}<>))<>>)}{}<>>)<{({}[()]<({}<>)<>([][()])({()<({}[()]<({}<({}<>)<>>)>)>}{}<>){({}[()]<({}<>)<>>)}{}<>>)}{}<>([]){{}({}<>)<>([])}{}<>([]){(({}[()])<{({}[()]<({}<({}<>)<>>)>)}{}<>([]){{}({}<>)<>([])}{}<>>)}{}>)

Its a bit of a big one but here's how it works:

Start by pushing n. n is the depth of the duplicate. We also open two parentheses. These allow us to store the value of the n in the scope until its needed again.

(((n)<

Next we loop n times each time pushing the top value of the stack to the off stack twice. This makes the initial duplicates for each number on the stack.

{({}[()]<(({}<>))<>>)}{}

Now we have two copies of each number on the offstack. We need to separate these into two groups.

So we switch to the offstack and recall one of the ns we saved at the beginning.

<>>)

We loop n times.

{({}[()]<...>)}{}

Each time we move one copy to the mainstack.

({}<>)<>

And roll one copy to the bottom of the stack. (This assumes the offstack was empty to begin with making this duplicate not stack clean)

([][()])ROLLER

Once that is done we have split the original into two groups the "original" and a copy on the offstack (the copy is actually in reverse). So we just move the copy to the main stack and we can be done with it.

([]){{}({}<>)<>([])}{}<>

Skeleton program

Now that I have made all of the pieces of the program, I just have to insert them into a frame.

The frame doubles the text one less than the stack's height times Using duplicate.

(([])[()])
{
 ({}[()]<
  DUPLICATE 
 >)
>)}{}

And then reverses the stack in decreasing increments of the initial stack height from n^2-n to 0.

(({}))
{
 (({}[()])<
  ({}<>)<>(({}))({<({}[()])><>({})<>}{})<>{}<>
  ({}<({}<>)<>>)<>({}<>)
  ({}<
   REVERSE
  >)
 >)
}{}{}
\$\endgroup\$
1
  • 5
    \$\begingroup\$ Amazing. You always blow my mind with what this language can do! :D \$\endgroup\$
    – DJMcMayhem
    Commented Sep 15, 2016 at 6:26
14
\$\begingroup\$

Jelly, 4 3 bytes

,Ṛṁ

Try it online! or Verify all test cases.

Saved a byte thanks to @Maltysen.

Explanation

,Ṛṁ  Input: string S
 Ṛ    Reverse S
,     Join S with reverse of S. Makes a list [S, rev(S)]
  ṁ   Mold [S, rev(S)] to len(S) by repeating elements cyclically
      Return and print implicitly as a string
\$\endgroup\$
5
  • 1
    \$\begingroup\$ mold doesn't need the L \$\endgroup\$
    – Maltysen
    Commented Sep 15, 2016 at 3:35
  • \$\begingroup\$ @Maltysen wow thanks, did you know that from the source code or from experience \$\endgroup\$
    – miles
    Commented Sep 15, 2016 at 3:36
  • \$\begingroup\$ from experience, I don't know Jelly, but I kinda guessed that's what mold would do on a non-number, since Jelly doesn't really do overloads, also mold kinda reminded me of reshape from J \$\endgroup\$
    – Maltysen
    Commented Sep 15, 2016 at 3:39
  • \$\begingroup\$ mold actually takes only iterables, but it casts integers to range first. \$\endgroup\$
    – Dennis
    Commented Sep 15, 2016 at 3:39
  • 1
    \$\begingroup\$ Yeah I treated mold as reshape so I just habitually gave it a number. There's so many neat little treats in Jelly, like how an array of strings is just automatically output as a concatenated string \$\endgroup\$
    – miles
    Commented Sep 15, 2016 at 3:41
11
\$\begingroup\$

PHP, 54 52 bytes

(49 bytes, but do not work if string contains '0')

for(;($a=$argv[1])[$i++];)echo$i%2?$a:strrev($a);

(52 bytes)

<?=str_pad('',strlen($a=$argv[1])**2,$a.strrev($a));

(54 bytes)

for(;$i++<strlen($a=$argv[1]);)echo$i%2?$a:strrev($a);
\$\endgroup\$
1
  • \$\begingroup\$ I completely forgot about str_pad. nice one! \$\endgroup\$
    – Titus
    Commented Sep 15, 2016 at 7:23
10
\$\begingroup\$

2sable, 3 bytes

Code:

gGÂ

Explanation:

g   # Get the length of the input
 G  # Do the following n - 1 times:
  Â # Bifurcate, which duplicates a and reverses the duplicate

Uses the CP-1252 encoding. Try it online!

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

J, 13 8 bytes

Saved 5 bytes thanks to miles!

#;@$];|.

This is a 5-train with the following verbs:

# ;@$ ] ; |.

The inner fork is composed of ] (identity), ; (link), and |. (reverse). Observe:

   (| ; |.) 'Hello!'
+------+------+
|Hello!|!olleH|
+------+------+

The outer two verbs make the rest of the train. # is, in this case, the size of the argument, that is, the length. The verb linking these is ;@$, or ravel over reshape. Observe:

   # 'Hello!'
6
   6 $ (] ; |.) 'Hello!'
+------+------+------+------+------+------+
|Hello!|!olleH|Hello!|!olleH|Hello!|!olleH|
+------+------+------+------+------+------+
   ; 6 $ (] ; |.) 'Hello!'
Hello!!olleHHello!!olleHHello!!olleH
   6 ;@$ (] ; |.) 'Hello!'
Hello!!olleHHello!!olleHHello!!olleH
   (# ;@$ (] ; |.)) 'Hello!'
Hello!!olleHHello!!olleHHello!!olleH
   (# ;@$ ] ; |.) 'Hello!'
Hello!!olleHHello!!olleHHello!!olleH
   (#;@$];|.) 'Hello!'
Hello!!olleHHello!!olleHHello!!olleH

Old solution.

[:,|.^:(i.@#)

Simple enough. |. is reverse, and ^: is power conjunction, which repeats it's left verb (right hand) # of times. When the right argument is a verb, that verb is called on the argument. The right verb in this case is range from zero (i.) to the length (#). When raised to an array, the intermediate results are kept. All that needs to be done is to flatten the array with ,.

Intermediate results

   (i.@#) 'Hello!'
0 1 2 3 4 5
   |.^:0 1 2 3 4 5 'Hello!'
Hello!
!olleH
Hello!
!olleH
Hello!
!olleH
   |.^:(i.@#) 'Hello!'
Hello!
!olleH
Hello!
!olleH
Hello!
!olleH
   ([:,|.^:(i.@#)) 'Hello!'
Hello!!olleHHello!!olleHHello!!olleH
\$\endgroup\$
3
  • \$\begingroup\$ You can save a byte by boxing the length <@# \$\endgroup\$
    – miles
    Commented Sep 15, 2016 at 3:25
  • \$\begingroup\$ A neat 8 byte solution is #;@$];|. which boxes the initial and reverse, reshapes the boxed strings and razes them together \$\endgroup\$
    – miles
    Commented Sep 15, 2016 at 3:42
  • \$\begingroup\$ @miles whoa, that's pretty neat. \$\endgroup\$ Commented Sep 15, 2016 at 11:09
7
\$\begingroup\$

Ruby, 39 bytes

->(s){s.reverse!.gsub(/./){s.reverse!}}

I suck at Ruby. Golfing help is appreciated.

Ruby is a really nice language for this because of .reverse!

Explanation

I was hoping it would be someting simple like:

s.gsub(/./){s.reverse!}

but because of boilerplate/challenge restriction it's longer.

What s.reverse! is very useful. s.reverse! is basically s = s.reverse!, meaning it also mutates s.


What each section of the program does is described below:

->(s){             # Lambda with argument s
      s.reverse!   # Reverse `s` see above for details
      .gsub(/./)   # Replace every character with...
      {s.reverse!} # the input reversed!

The thing about s.reverse! that is great is that everytime it is evaluated the string get's flipped. So as it replaces the string. s is modified!

\$\endgroup\$
7
  • \$\begingroup\$ With the -p flag you can save 4 bytes: $_.reverse!;gsub(/./){$_.reverse!} \$\endgroup\$
    – Jordan
    Commented Sep 15, 2016 at 3:35
  • \$\begingroup\$ @Jordan would't I need a .chomp though on the $_? it seems to include the newline at the moment \$\endgroup\$
    – Downgoat
    Commented Sep 15, 2016 at 3:47
  • \$\begingroup\$ Not if you do something like ruby -pe '$_.reverse!;gsub(/./){$_.reverse!}' < file.txt where file.txt is a line without the trailing newline :V Anyways, if you decide not to do that, you don't need parens on the lambda so ->s works \$\endgroup\$
    – Value Ink
    Commented Sep 15, 2016 at 5:56
  • \$\begingroup\$ @ValueInk, you can provide newlineless input without file if you pipe it. Or you can even type it manually, just not press Enter: i.sstatic.net/6luxM.png \$\endgroup\$
    – manatwork
    Commented Sep 15, 2016 at 9:07
  • 1
    \$\begingroup\$ You don't need parentheses around the lambda's argument. Also, I think you can shave off one of the exclamation points: s.gsub(/./){s.reverse!.reverse} \$\endgroup\$
    – m-chrzan
    Commented Sep 18, 2016 at 0:23
7
\$\begingroup\$

Perl, 24 bytes

Includes +2 for -lp

Give input on STDIN:

rev.pl <<< Hello!

rev.pl:

#!/usr/bin/perl -lp
s%.%s/.?/chop/eg;$`%eg

Surprisingly this does not use the builtin reverse operator. That name is just soooo long, all solutions I could think of with reverse are at least 1 byte longer.

\$\endgroup\$
1
  • \$\begingroup\$ Upvoted for finding a solution that takes less bytes than a built-in \$\endgroup\$
    – MilkyWay90
    Commented Mar 17, 2019 at 22:24
6
\$\begingroup\$

JavaScript (ES 6), 59 50 bytes

9 Bytes thanks to Hedi and Huntro.

f=(s,n=1)=>s[n]?s+f([...s].reverse().join``,n+1):s

recursive function.

Reversing the string takes almost half of the size (25 22 bytes!) ...
Why isn´t there a native way for that?

\$\endgroup\$
7
  • 1
    \$\begingroup\$ You could use s[n]?... intead of n<s.length?... \$\endgroup\$
    – Hedi
    Commented Sep 15, 2016 at 6:26
  • 1
    \$\begingroup\$ You can also save 3 bytes by using [...s] instead of s.split`` \$\endgroup\$
    – Huntro
    Commented Sep 15, 2016 at 7:02
  • \$\begingroup\$ yea 36 bytes ideally f=(s,n=1)=>n==1?s:s+s.reverse(),n-1) \$\endgroup\$
    – caub
    Commented Sep 15, 2016 at 13:52
  • \$\begingroup\$ non recursive one f=(s,n=1)=>Array.from({length:n},(_,i)=>i%2?s.reverse():s).join``) that would too be better with some better function for range \$\endgroup\$
    – caub
    Commented Sep 15, 2016 at 13:58
  • \$\begingroup\$ @caub: SyntaxError: Unexpected token ) JS has no native string reversion. SyntaxError: Invalid or unexpected token for your second suggestion. What browser does that work in? \$\endgroup\$
    – Titus
    Commented Sep 15, 2016 at 16:48
5
\$\begingroup\$

Minkolang, 17 bytes:

$oId$z$Dz[rz[O]].

Try it here!

Explanation

$o                   Read in whole input as characters
  Id                 Push the length of stack and duplicate
    $z               Pop top of stack and store in register (z)
      $D             Pop top of stack (n) and duplicate whole stack n-1 times
        z[     ]     z times, do the following:
          r          Reverse the stack
           z[O]      z times, pop the top of stack and output as character
                .    Stop.
\$\endgroup\$
5
\$\begingroup\$

Pip, 11 10 bytes

L#aORVRV:a

Try it online!

Explanation:

            a is first cmdline argument (implicit)
L#a         Loop len(a) times:
      RV:a   Reverse a and assign back to a
   ORV       Output the reverse of a (since it needs to go forward first then backward)
\$\endgroup\$
1
  • \$\begingroup\$ Somehow I'm unable to find a shorter solution with RF to this. \$\endgroup\$
    – Razetime
    Commented Sep 4, 2020 at 6:19
5
\$\begingroup\$

Haskell, 40 36 32 Bytes

m s=take(length s^2)$cycle$s++reverse s

Example:

*Main> m "Hello!"
"Hello!!olleHHello!!olleHHello!!olleH"

Even shorter (credit to Damien):

q s=zip(s>>[s,reverse s])s>>=fst

s>>[s,reverse s] cycles ["abc","cba",...] which is zipped to correct size and concatMap'ped with fst

\$\endgroup\$
2
  • 2
    \$\begingroup\$ q s=zip(s>>[s,reverse s])s>>=fst \$\endgroup\$
    – Damien
    Commented Sep 15, 2016 at 11:23
  • 3
    \$\begingroup\$ Or Pointfree one with same size: (>>=fst).(iterate reverse>>=zip) \$\endgroup\$
    – Damien
    Commented Sep 15, 2016 at 11:33
5
\$\begingroup\$

MATL, 13 12 8 bytes

Pushes all elements, combines in the end.

td"tP]&h

td"  ]     %For loop over string length - 1 due to diff
   tP      %Push copy of string, reverse
      &h   %Concatenate entire stack horizontally
        

Try it online!


Old versions:

Completely different approach, based on fprintf:

t"t1$0#YDP]x

t"        ]   % For loop over string
  t           % Duplicate string for printing:
   1$0#YD     % `fprintf` with 1 input, 0 output (i.e., to screen).
         P    % Reverse
           x  % Empty stack to prevent implicit output

Version based on reversing a template string

ttd"wPtbYc]Dx

t                 %Duplicate input, to create 'accumulator' string 
                  % (alongside the input string which will serve as 'template'
 td               %Duplicate input, diff to get an stringof size input-1
   "       ]      %For loop over size n-1 string (consumes diff'd string)
     wP           %Get 'template' string on top of stack, and reverse
       tb         %Duplicate template string, and switch with 'accumulator' string
         Yc       %Concatenate template string with accumulator. 
            Dx   %Display top element, delete template string to prevent implicit disp
\$\endgroup\$
2
  • \$\begingroup\$ I like the clever usage of td! \$\endgroup\$
    – DJMcMayhem
    Commented Sep 18, 2016 at 1:02
  • \$\begingroup\$ @DJMcMayhem Thanks! I had the obvious tnq:" first, but tn:" is a bit of a code smell (see this Matlab golfing tip) so I figured that tnq: could be more compact, too. \$\endgroup\$
    – Sanchises
    Commented Sep 18, 2016 at 8:24
5
\$\begingroup\$

8088 Assembly, IBM PC DOS, 29 28 bytes

Assembled, xxd dump:

00000000: d1ee ac48 938a cbfc 518a cbf7 da78 01fd  ...H....Q....x..
00000010: acac b40e cd10 e2f9 59e2 ecc3            ........Y...

Unassembled listing:

D1 EE       SHR  SI, 1          ; point SI to DOS PSP (080H) 
AC          LODSB               ; load input string length into AL 
48          DEC  AX             ; remove leading space from length counter 
93          XCHG BX, AX         ; save input length to BL 
8A FB       MOV  BH, BL         ; string output counter in BH 
        S_LOOP: 
FC          CLD                 ; set direction forward 
8A CB       MOV  CL, BL         ; reset char counter in CL 
F7 DA       NEG  DX             ; flip DX to toggle fwd/back output 
78 01       JS   C_START        ; if positive, go forward 
FD          STD                 ; otherwise go backwards 
        C_START: 
AC          LODSB               ; adjust SI to first/last char
        C_LOOP: 
AC          LODSB               ; load next char into AL
B4 0E       MOV  AH, 0EH        ; PC BIOS tty output function
CD 10       INT  10H            ; write char to console
E2 F9       LOOP C_LOOP         ; continue looping through chars
FE CF       DEC  BH             ; decrement string count loop
75 EC       JNZ  S_LOOP         ; if not zero, continue loop
C3          RET                 ; exit to DOS

Standalone PC DOS executable program. Input string via command line, output is console.

enter image description here

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

Perl 6,  31  30 bytes

{[~] (|($_,.flip)xx*)[^.chars]}

Save one byte by misusing .ords, which returns a list of ordinals, then implicitly turn that into a number to create a range with.

{[~] (|($_,.flip)xx*)[^.ords]}

Explanation:

# bare block lambda with implicit parameter 「$_」
{
  # reduce using string concatenation operator 「~」
  [~]

  (
    # create a Slip
    |(
      # of the input, and its string reverse
      $_, .flip

    # list repeated infinitely
    ) xx *

  # get the values in the range from 0 up-to and excluding
  # the number of characters 「0 ..^ +$_.ords」
  )[ ^.ords ]
}

Usage:

my &code = {[~] (|($_,.flip)xx*)[^.ords]}

say code 'a'; # a
say code 'abcd'; # abcddcbaabcddcba
say code 'OK!'; # OK!!KOOK!
say code 4815162342; # 4815162342243261518448151623422432615184481516234224326151844815162342243261518448151623422432615184
\$\endgroup\$
4
\$\begingroup\$

Vim + coreutils, 32 keystrokes

You can never have too many Vim answers.

qqYv:!rev
Pjq@=len(@")
@q2dkv{gJ

Explanation

qq               " Start recording macro
Y                " Yank (copy) line
v:!rev<CR>       " Reverse line with coreutils rev command
Pj               " Paste yanked line above this line
q                " Stop recording
@=len(@")<CR>@q  " Playback macro once for each character
2dk              " Delete last 3 lines
v{gJ             " Join lines
\$\endgroup\$
1
  • 1
    \$\begingroup\$ With coreutils? That's cheating! :P \$\endgroup\$ Commented Sep 20, 2016 at 19:42
4
\$\begingroup\$

Scala, 73 72 71 bytes

def f(s:String)=for(i<-1 to s.length){print(if(i%2>0)s else s.reverse)}

This is my first attempt at code golfing, so I'm sure there are countless improvements.

Update:

Golfed away 1 byte by removing brackets.

Thanks to Destructible Watermelon for suggestion, shaved off a byte.

\$\endgroup\$
2
  • \$\begingroup\$ I don't know scala, but can you change i%2==1 to i%2>0? \$\endgroup\$ Commented Sep 18, 2016 at 0:59
  • \$\begingroup\$ @DestructibleWatermelon Hadn't thought of that, yes I can \$\endgroup\$ Commented Sep 18, 2016 at 1:40
3
\$\begingroup\$

PowerShell v2+, 57 bytes

param($a)-join(1..($x=$a.length)|%{($a[$x..0],$a)[$_%2]})

No real clean way to get string lengths or reverse 'em, so this is pretty lengthy.

Takes input $a, loops from 1 to $a.length (stored in $x for use later). Each iteration we use a pseudo-ternary to index into an array of either $a or $a[$x..0] (i.e., reversed), based on whether our input number is odd/even [$_%2]. These are all encapsulated in parens and -joined together to form a single string. That's left on the pipeline, and output is implicit.

PS C:\Tools\Scripts\golfing> .\stringgnirts.ps1 'TimmyD'
TimmyDDymmiTTimmyDDymmiTTimmyDDymmiT
\$\endgroup\$
3
\$\begingroup\$

Dyalog APL, 8 bytes

∊≢⍴⊂,⊂∘⌽

flatten

the tally

cyclically reshaping

the enclosed argument

, followed by

⊂∘⌽ the enclosed reversed argument

TryAPL online!

-1 byte thanks to jimmy23013.

\$\endgroup\$
2
  • \$\begingroup\$ ∊≢⍴⊂,⊂∘⌽. And you counted 1 byte less. \$\endgroup\$
    – jimmy23013
    Commented Sep 15, 2016 at 13:33
  • \$\begingroup\$ @jimmy23013 I wrote the final score. ;-) \$\endgroup\$
    – Adám
    Commented Sep 15, 2016 at 15:23
3
\$\begingroup\$

Cubix, 52 bytes

Ap\:\;.#u/\:qqsoq(?;u.q..$u<../pB@u:\.....\(?q..s..p

On a cube:

      A p \
      : \ ;
      . # u
/ \ : q q s o q ( ? ; u
. q . . $ u < . . / p B
@ u : \ . . . . . \ ( ?
      q . .
      s . .
      p . .

This one was fun; there are bytes still to be golfed out of this but this will definitely work.

Try it online!

explanation:

Input of ABC

  • /A : go north and read in all inputs as characters; -1 will be at the bottom
  • p\;. : remove the -1 from the stack
  • u# : push the string length (number of items on the stack)
  • \:\:qq : dup the string length twice, push two copies to bottom of stack
  • loop:

    • soq(?/<u : swap top of stack, ouptut top of stack as ASCII, push top (letter) to bottom, decrement top of stack, turn right if not done, then move IP to the right place.
    • at end of loop, the stack will look like C B A 3 3 0
  • ;u : pop top of stack C B A 3 3

  • B : reverse stack 3 3 A B C
  • p( : move bottom to top and decrement 3 A B C 2
  • ? if top is zero, go straight to @ and terminate
  • else
    • psq:uq : move bottom to top, swap top and move top to bottom dup, and move top to bottom 3 2 A B C 3
    • $u : skip u
    • < puts us back into the loop.

Interpreter

\$\endgroup\$
2
  • \$\begingroup\$ Here's a 24 bytes one. Same general logic just compressed a little. \$\endgroup\$
    – MickyT
    Commented Mar 21, 2019 at 21:42
  • \$\begingroup\$ @MickyT I'd feel bad about taking credit for 28 bytes of golfing. Post it yourself! \$\endgroup\$
    – Giuseppe
    Commented Mar 22, 2019 at 13:37
3
\$\begingroup\$

C (gcc), 88 87 85 83 68 66 83 82 78 bytes

-1 thanks to ceilingcat

Old version

p,q;f(char*s){p=q=1;for(char*m=s--;*m;s[p+=q]*p?:(m++,p+=q=-q))putchar(s[p]);}

Try it online!

Shorter version (slightly broken)

Riffing on the 76 byte approach by ASCII-only in the comments, and -1 byte from his tweak of my tweak.

Edit: This version is slightly broken in that it assumes that every string is preceded by a NULL byte, which is not always true. (See last test case in link). Reverting to the 83 byte version for now.

f(char*s){for(char*n=s-1,k=1;*s++;k=-k)for(;*(n+=k);)putchar(*n);}

Try it online!

\$\endgroup\$
6
  • \$\begingroup\$ 67 \$\endgroup\$
    – ASCII-only
    Commented Mar 23, 2019 at 2:29
  • \$\begingroup\$ @ASCII-only 68 is possible with some tweaking. \$\endgroup\$
    – gastropner
    Commented Mar 23, 2019 at 2:31
  • \$\begingroup\$ :P it's 67 now lol @gastropner \$\endgroup\$
    – ASCII-only
    Commented Mar 23, 2019 at 2:32
  • \$\begingroup\$ @ASCII-only 66 :-P \$\endgroup\$
    – gastropner
    Commented Mar 23, 2019 at 2:36
  • \$\begingroup\$ @ASCII-only Sadly, the short version turns out to not work in certain cases. \$\endgroup\$
    – gastropner
    Commented Mar 23, 2019 at 2:49
3
\$\begingroup\$

brainfuck, 71 49 43 bytes

,[>+[>+<-],]>[<<[<]>[.>]>-[<<[.<]>[>]>-<]>]

Try it online!

Thanks to Jo King for saving 6 bytes.

[Tape: [Letters], 0, counter]
,[          while input
  >+        increment old counter
  [>+<-]    move counter to next position
  ,         input next
]
>[          while counter
  <<[<]>    go to first letter
  [.>]      print word forwards
  >-        decrement counter
  [         if counter
    <<      go to last letter
    [.<]    print word backwards
    >[>]>-  decrement counter
    <       exit if
  ]
  >         go to counter
]
\$\endgroup\$
0
2
\$\begingroup\$

Java, 127 111 88 bytes

(s,r)->{for(int i=0;i++<s.length();)r+=i%2<1?new StringBuffer(s).reverse():s;return r;};

Ungolfed test program

    public static void main(String[] args) {
    BiFunction<String, String, String> func = (s, r) -> {
        for (int i = 0; i++ < s.length();) {
            r += i % 2 < 1 ? new StringBuffer(s).reverse() : s;
        }
        return r;
    };
    System.out.println(func.apply("Hello!", ""));
}
\$\endgroup\$
3
  • \$\begingroup\$ This can be golfed some more: (s,r)->{for(int i=0;i++<s.length();)r+=i%2<1?s:new StringBuffer(s).reverse();return r;}; (88 bytes). Also, I would specify that this is Java 8. \$\endgroup\$ Commented Sep 15, 2016 at 8:26
  • \$\begingroup\$ Na, it's fine to assume that his is using the latest version of Java. \$\endgroup\$
    – Shaun Wild
    Commented Sep 15, 2016 at 9:46
  • \$\begingroup\$ @KevinCruijssen Java 7 is not supported anymore (except with big $$$). We shouldn't have to specify the version of Java. Also, if you write as Java 7, most of the answers can be written in Java 1.1 or 1.2. So shouldn't you write the lowest version with which it works? If the code in this answer was Java 7 compliant, it'd be Java 1.2 compliant, and... would still work in Java 8. \$\endgroup\$ Commented Sep 15, 2016 at 12:18
2
\$\begingroup\$

R, 53 bytes

Assumes that the input is space- or newline-separated for each character.

cat(rep(c(i<-scan(,""),rev(i)),l=length(i)^2),sep="")

Some test cases:

> cat(rep(c(i<-scan(,""),rev(i)),len=length(i)^2),sep="")
1: h e l l o !
7: 
Read 6 items
hello!!ollehhello!!ollehhello!!olleh

> cat(rep(c(i<-scan(,""),rev(i)),l=length(i)^2),sep="")
1: a
2: 
Read 1 item
a

> cat(rep(c(i<-scan(,""),rev(i)),l=length(i)^2),sep="")
1: a b c d
5: 
Read 4 items
abcddcbaabcddcba

> cat(rep(c(i<-scan(,""),rev(i)),l=length(i)^2),sep="")
1: O K !
4: 
Read 3 items
OK!!KOOK!

> cat(rep(c(i<-scan(,""),rev(i)),l=length(i)^2),sep="")
1: 4 8 1 5 1 6 2 3 4 2
11: 
Read 10 items
4815162342243261518448151623422432615184481516234224326151844815162342243261518448151623422432615184

> cat(rep(c(i<-scan(,""),rev(i)),l=length(i)^2),sep="")
1: P P C G
5:    
Read 4 items
PPCGGCPPPPCGGCPP

> cat(rep(c(i<-scan(,""),rev(i)),l=length(i)^2),sep="")
1: 4 2
3: 
Read 2 items
4224
\$\endgroup\$
2
\$\begingroup\$

Java, 151 bytes

public static void r(String s){String t = new StringBuffer(s).reverse().toString();for(int i=0;i<s.length();i++){System.out.print(((i%2==1)?t:s));}}

}

Ungolfed:

public static void r(String s) {
    String t = new StringBuffer(s).reverse().toString();
    for(int i = 0; i < s.length();i++) {
        System.out.print(((i % 2 == 1) ? t : s));
    }
}

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Hi, welcome to PPCG! First of all I'd like to recommend to read through Tips for golfing in Java. As for your code, there are a few things that can still be golfed: You can remove the public static before your method. You can remove the spaces between t=new StringBuffer. You can remove the unnecessary parenthesis and brackets. And you can swap the module check from ==1 to <1 (which is equivalent to ==0 for non-negative numbers). Also, you can move the i++ to the last usage inside the for-loop. \$\endgroup\$ Commented Sep 15, 2016 at 6:59
  • 6
    \$\begingroup\$ So in total it becomes: void r(String s){for(int i=0;i<s.length();)System.out.print(i++%2<1?s:new StringBuffer(s).reverse()+"");} (105 bytes) \$\endgroup\$ Commented Sep 15, 2016 at 7:01
2
\$\begingroup\$

C#, 94 bytes

using System.Linq;string R(string n)=>string.Concat(n.SelectMany((c,i)=>1>i%2?n:n.Reverse()));

76 bytes for the method + 18 bytes for LINQ import.

How it works:

using System.Linq; // Required for LINQ extension methods.

string R(string n) => 
    string.Concat( // Concatenate the following chars into a single string
        n.SelectMany( // Enumerate each char in n, flattening the returned IEnumerable<char>'s into a single IEnumerable<char>
            /*IEnumerable<char> Lambda*/(/*char*/ c, /*int*/ i) => // i = index in n
                1 > i % 2 // Check if i is even or odd
                    ? n // if i is even, add n to the concat
                    : n.Reverse() // else reverse n and concat that
        )
    )
;
\$\endgroup\$
2
\$\begingroup\$

Julia, 42 bytes

h(s,l=1)=l==endof(s)?s:s*h(reverse(s),l+1)

Recursive function with counter variable l. If it is equal to the length of the string s, simply return it, otherwise concatenate (s*...) it with h(reverse(s),...) while incrementing the counter l+1.

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

CJam, 10 bytes

l_,({_W%}*

Try it online!

Explanation

l            e# Read line
 _           e# Duplicate
  ,(         e# Length minus 1
    {   }*   e# Run code block that many times
     _       e# Duplicate
      W%     e# Reverse
             e# Implicitly display
\$\endgroup\$
2
\$\begingroup\$

Octave, 39 35 bytes

@(x)[x'+~x;flip(x'+~x),''](1:end/2)

f('Hello!')
ans = Hello!!olleHHello!!olleHHello!!olleH

Explanation:

@(x)            % Take x as input, inside apostrophes 'Hello!'
x'+~x           % Create a mesh of the ASCII-code of the input letters
                % For input `bcd` this will be:
                %    98    98    98
                %    99    99    99
                %   100   100   100
;flip(x'+~x)   % Concatenate vertically to create:
                %    98    98    98
                %    99    99    99
                %   100   100   100
                %   100   100   100
                %    99    99    99
                %    98    98    98
___,'']         % Short cut to convert ASCII-code to characters
(1:end/2)       % Display the first half of this array of letters, as a
                % horizontal string

Saved 4 bytes thanks to Luis. ~x instead of 0*x saved one byte (works because all elements of x are non-zero. flip instead of flipud saved another two bytes (I didn't know flip existed).

\$\endgroup\$
0

Your Answer

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

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