The goal here is to simply reverse a string, with one twist:
Keep the capitalization in the same places.

Example Input 1: Hello, Midnightas
Example Output 1: SathginDim ,olleh

Example Input 2: .Q
Exmaple Output 2: q.


  • Output to STDOUT, input from STDIN
  • The winner will be picked 13th of July on GMT+3 12:00 (One week)
  • The input may only consist of ASCII symbols, making it easier for programs that do not use any encoding that contains non-ASCII characters.
  • Any punctuation ending up in a position where there was an upper-case letter must be ignored.
  • \$\begingroup\$ Is that with or without the outprinting? Is that with or without the string? \$\endgroup\$ – user44904 Jul 6 '16 at 14:08
  • \$\begingroup\$ "Any punctuation ending up in a position where there was an upper-case letter must be ignored.", isn't the second example inconsistent with this rule? \$\endgroup\$ – Stefano Sanfilippo Aug 19 '16 at 13:10
  • \$\begingroup\$ It is consistent with the rule because punctuations do not have an uppercase variation. \$\endgroup\$ – user47018 Aug 19 '16 at 14:13

37 Answers 37


TCC - 4 bytes


Try it online!


     - output is implicit in TCC
<>   - reverse string
  c  - preserve capitalization
   i - get input
  • 11
    \$\begingroup\$ Did this work with a version of tcc.lua before the challenge was posted? Given that you've recently added commands to solve three other challenges, I assume it didn't. If your answer requires a version of the language that postdates the challenge, you must label it as non-competing in the header. I'll remove my downvote when you add the label or provide proof that your code worked in an earlier version. \$\endgroup\$ – Dennis Jul 26 '16 at 17:07

Python, 71 bytes

lambda s:''.join((z*2).title()[c.isupper()-1]for c,z in zip(s,s[::-1]))

Try it online

-3 bytes from Ruud, plus the inspiration for 2 more.

-4 more bytes from FryAmTheEggman

  • \$\begingroup\$ lambda s:''.join([z.lower(),z.upper()][c.isupper()]for c,z in zip(s,s[::-1])) is three bytes shorter \$\endgroup\$ – Arfie Jul 6 '16 at 13:03
  • 1
    \$\begingroup\$ @Ruud Thanks! Moving the function call to outside of the list selection saves 2 more! \$\endgroup\$ – user45941 Jul 6 '16 at 13:06
  • 2
    \$\begingroup\$ (z*2).title()[c.isupper()-1] should work. \$\endgroup\$ – FryAmTheEggman Jul 6 '16 at 15:10
  • 6
    \$\begingroup\$ You could win another byte with ~c.isupper() instead of c.isupper()-1 \$\endgroup\$ – Lulhum Jul 6 '16 at 18:01
  • \$\begingroup\$ This doesn't get input from stdin or output to stdout... \$\endgroup\$ – ArtOfWarfare Jul 7 '16 at 16:11

Python 2, 73 bytes

Since the rules specify the input is ascii:

lambda s:''.join([z.lower,z.upper]['@'<c<'[']()for c,z in zip(s,s[::-1]))

All the credit goes to @Mego though, but I had not the reputation to just comment on his answer.

  • \$\begingroup\$ Can you use the ascii value of '@' and '[' to gain 2 bytes? \$\endgroup\$ – aloisdg Jul 6 '16 at 17:17
  • \$\begingroup\$ Unfortunately no, I'd have to use ord(c), integer and string comparison do not cope very well in Python \$\endgroup\$ – Lulhum Jul 6 '16 at 17:50
  • \$\begingroup\$ Pretty much what I got, but you were first +1 \$\endgroup\$ – orlp Jul 6 '16 at 19:20

Perl, 31 + 2 (-lp) = 33 bytes

This solution is from @Ton Hospel (13 bytes shorter thant mine).

s%.%(lc$&gt$&?u:l)."c chop"%eeg

But you'll need l and p switches on. To run it :

perl -lpe 's%.%(lc$&gt$&?u:l)."c chop"%eeg'
  • 5
    \$\begingroup\$ Hello, and welcome to PPCG! This is great! \$\endgroup\$ – NoOneIsHere Jul 6 '16 at 14:41
  • \$\begingroup\$ Very nice indeed! I've never used-a autosplit, I feel I could have used this many times in the past! I need to remember that! I think you can save another byte using map...,... instead of map{...}... as you have $F at the start though! :) \$\endgroup\$ – Dom Hastings Jul 7 '16 at 7:33
  • \$\begingroup\$ Shorter code (31+2 bytes): perl -lpe 's%.%(lc$&gt$&?u:l)."c chop"%eeg \$\endgroup\$ – Ton Hospel Aug 17 '16 at 21:39
  • \$\begingroup\$ Notice that -a is implied by -F \$\endgroup\$ – Ton Hospel Aug 17 '16 at 21:43
  • \$\begingroup\$ @TonHospel wow, thank you very much and well done, that's some quite nice code! About -a (and -n) being implied by -F, I read it a while ago on perlrun, tried it, but it didn't work; but I tried it again now and it works fine so I'm guessing I did something wrong back then. Thanks. \$\endgroup\$ – Dada Aug 18 '16 at 15:48

Pyth, 13 11 10 9 bytes

Thanks to @FryAmTheEggman for reminding me about V and @LeakyNun for another byte.


Try it online! now on mobile, updating link in a bit

  • \$\begingroup\$ srV_Qm!rId0 is 11, but I think it might be possible to shorten that map... \$\endgroup\$ – FryAmTheEggman Jul 6 '16 at 13:45
  • \$\begingroup\$ @FryAmTheEggman Remove the d and you saved a byte. \$\endgroup\$ – Leaky Nun Jul 6 '16 at 22:42
  • \$\begingroup\$ srV_Qm!/G should save a byte \$\endgroup\$ – Leaky Nun Jul 6 '16 at 22:45

Python, 66 bytes

f=lambda s,i=0:s[i:]and(s[~i]*2).title()[~('@'<s[i]<'[')]+f(s,i+1)

Recurses through the indices i, taking the character s[~i] from the back and the case of s[i] from the front. Being capital is checked as lying in the contiguous range @ABC...XYZ[. Credit to FryAmTheEggman from the (_*2).title() trick.


Retina, 75 67 65 bytes

Byte count assumes ISO 8859-1 encoding.




Try it online! (The first line enables a test suite with multiple linefeed-separated test cases.)


JavaScript (ES6), 95 83 bytes


Edit: Saved a massive 12 bytes thanks to @edc65.

  • \$\begingroup\$ s=>r=[...l=s.toLowerCase()].reverse().map((c,i)=>s[i]!=l[i]?c.toUpperCase():c).join`` -10 \$\endgroup\$ – edc65 Jul 6 '16 at 15:02
  • \$\begingroup\$ @edc65 Thanks! (Note: the r= is unnecessary.) \$\endgroup\$ – Neil Jul 6 '16 at 15:15

Pyke, 11 10 9 bytes


Try it here!

_         -   reversed(input)
 F        -  for i in ^
   o      -      o+=1
  Q @     -     input[^]
     Uh   -    ^.is_upper()+1
       Al -   [len, str.lower, str.upper, ...][^](i)
          - "".join(^)
  • \$\begingroup\$ It first gave me an error, then at the same time the correct answer. i.imgur.com/uTcH27F.png \$\endgroup\$ – user47018 Jul 10 '16 at 8:48
  • \$\begingroup\$ That always happens, you can click disable warnings to turn that off. \$\endgroup\$ – Blue Jul 10 '16 at 8:49
  • \$\begingroup\$ Aha, okay. Sorry, I'm not good with Pyke \$\endgroup\$ – user47018 Jul 10 '16 at 8:50
  • \$\begingroup\$ Might be because I'm the only guy using it \$\endgroup\$ – Blue Jul 10 '16 at 8:50

05AB1E, 19 16 15 13 bytes

Thanks to Emigna for saving a 3 bytes!

Probably gonna get beat by Jelly... Code:


Uses the CP-1252 encoding. Try it online!.

  • \$\begingroup\$ S.l_v¹lRNèyiu}? is 1 byte shorter \$\endgroup\$ – Emigna Jul 6 '16 at 13:07
  • \$\begingroup\$ @Emigna Wow thanks! That is very clever. \$\endgroup\$ – Adnan Jul 6 '16 at 13:13
  • \$\begingroup\$ Âuvy¹Nè.lilë}? is 14. Just happy I can help you for once :) \$\endgroup\$ – Emigna Jul 6 '16 at 13:16
  • \$\begingroup\$ @Emigna That is amazing! Very nice use of bifurcate :). \$\endgroup\$ – Adnan Jul 6 '16 at 13:20
  • \$\begingroup\$ Ruvy¹Nè.lil}? actually. I didn't use the bifurcation and forgot to remove the else. So 13. \$\endgroup\$ – Emigna Jul 6 '16 at 13:21

Brachylog, 28 bytes



  • Main Predicate:

    @lr                 Reverse the lowercase version of the Input
       :?z              Zip that reversed string with the Input
          :1a           Apply predicate 1 to each couple [char i of reverse, char i of Input]
             c.         Output is the concatenation of the result
  • Predicate 1:

    h@u.,               Output is the uppercase version of the first char of Input
         @A@um~t?       The second char of Input is an uppercase letter
                 |      Or
                  h.    Output is the first char of Input

MATL, 13 bytes


Try it online!

Pk      % Implicit inpput. Flip, lowercase
t       % Duplicate
Gtk<    % Logical index of uppercase letters in the input string
)       % Get letters at those positions in the flipped string
Xk      % Make them uppercase
5M(     % Assign them to the indicated positions. Implicit display

J, 30 bytes

(={"_1 toupper@]|.@,.])tolower

Doesn't support non-ASCII

  • \$\begingroup\$ "toupper" "tolower" can't you use code points to shorten it? \$\endgroup\$ – Leaky Nun Jul 6 '16 at 22:50
  • \$\begingroup\$ @LeakyNun Maybe but I can't really say for sure \$\endgroup\$ – miles Jul 6 '16 at 23:40

TSQL, 175 bytes


DECLARE @ varchar(99)='Hello, Midnightas'

,@o varchar(99)='',@i INT=0WHILE @i<LEN(@)SELECT


DECLARE @ varchar(99)='Hello, Midnightas'

,@o varchar(99)=''
,@i INT=0

  SELECT @i+=1,@o+=IIF(ascii(x)=ascii(lower(x)),lower(y),upper(y))
    (SELECT SUBSTRING(@,@i+1,1)x,SUBSTRING(@,len(@)-@i,1)y)z



  • \$\begingroup\$ hardcoding the input ? \$\endgroup\$ – cat Jul 6 '16 at 18:15
  • \$\begingroup\$ @cat that is the only way. In sql, there is no STDIN or input command. If you look at stackoverflow that is how all the questions are solved - you can also look at my other answers on codegolf \$\endgroup\$ – t-clausen.dk Jul 6 '16 at 19:41
  • \$\begingroup\$ Oh, yeah, I definitely remember having this conversation wih a SQL user before (you, maybe). That's weird, but should be fine. \$\endgroup\$ – cat Jul 6 '16 at 19:44
  • 1
    \$\begingroup\$ @cat we have not had this conversation before, but you did help me with a byte count earlier \$\endgroup\$ – t-clausen.dk Jul 6 '16 at 19:56

Actually, 25 bytes


Try it online!


;                          create a copy of the input
 `úíuY"ùû"E£`M             for each character in input:
  úíuY                       0-based index in lowercase English letters, or -1 if not found, increment, boolean negate (1 if uppercase else 0)
      "ùû"E£                 `û` if the character is lowercase else `ù` (str.lower vs str.upper)
              @ùRZ         make the other copy of the input lowercase, reverse it, and zip it with the map result
                  `i@ƒ`M   for each (string, function) pair:
                   i@ƒ       flatten, swap, apply (apply the function to the string)
                        Σ  concatenate the strings

Haskell, 83 80 75 71 bytes

The most straightforward way I could think of.

import Data.Char
f a|isUpper a=toUpper|1>0=toLower
zipWith f<*>reverse
  • \$\begingroup\$ If you swap the parameters of (#), k can be rewritten in point-free style: k=reverse>>=zipWith(#), that saves a couple bytes :) \$\endgroup\$ – Flonk Jul 6 '16 at 18:53
  • \$\begingroup\$ The second line can be point-free in b as f a|isUpper a=toUpper|1>0=toLower, though this conflicts with Flonk's improvement. \$\endgroup\$ – xnor Jul 6 '16 at 19:23
  • \$\begingroup\$ You can use xnor's version of f and rewrite Flonk's k to zipWith f<*>reverse. \$\endgroup\$ – nimi Jul 6 '16 at 19:39
  • \$\begingroup\$ Don’t you need to eliminate the parameter s? \$\endgroup\$ – Lynn Jul 6 '16 at 20:17
  • \$\begingroup\$ Yes, and you're also allowed to cut the k=. \$\endgroup\$ – xnor Jul 6 '16 at 20:17

PowerShell, 154, 152, 99, 86 bytes

Thank you @TimmyD for saving me a whopping 47 bytes (I also saved an additional 6)

Thank you @TessellatingHeckler for saving an additional 13 bytes.





Normal formatting:

Latest (looks best as two lines in my opinion):

-join($a[$a.length..0] | %{("$_".ToLower(), "$_".ToUpper())[$a[$i++] -in 65..90]})


# Sets the first passed parameter to variable $a
         -join(                                                                      )
# Converts a char array to a string
# Reverses $a as a char array
                               |%{                                                  }
# Shorthand pipe to foreach loop
# Creates an array of the looped char in lower and upper cases
# Resolves to 1 if the current index of $a is upper, which would output "$_".ToUpper() which is index 1 of the previous array


$x = 0
(($a[-1..-$a.length]) | %{
    $_ = $_.tostring().tolower()
    if([regex]::matches($a,"[A-Z]").index -contains $x){
) -join ''

First time poster here, was motivated because I rarely see PowerShell, but at 154 152 bytes on this one... I can see why! Any suggestions appreciated.

I have learned that I must completely change my way of thinking to golf in code and its fun!

  • \$\begingroup\$ Hello, and welcome to PPCG! This is great! \$\endgroup\$ – NoOneIsHere Jul 6 '16 at 22:45
  • \$\begingroup\$ Welcome to PPCG! Nice to see another PowerShell user around here. You can cut out quite a bit by replacing the .tostring() with quotes, and by using ASCII integer manipulation rather than regex. Try the following, for 105 bytes -- param($a)-join($a[$a.length..0]|%{if(($x=$a[$i++])-le90-and$x-ge65){"$_".ToUpper()}else{"$_".ToLower()}}). \$\endgroup\$ – AdmBorkBork Jul 11 '16 at 15:07
  • \$\begingroup\$ Brilliant! We can make that even shorter by using a range instead of -le and -ge: param($a)-join($a[$a.length..0]|%{if(65..90-contains$a[$i++]){"$_".ToUpper()}else{"$_".ToLower()}}) \$\endgroup\$ – ThePoShWolf Jul 11 '16 at 15:49
  • \$\begingroup\$ X-inY is shorter than Y-containsX, and you can change your if for the fake ternary operator to get 86 bytes - param($a)-join($a[$a.length..0]|%{("$_".ToLower(),"$_".ToUpper())[$a[$i++]-in65..90]}) \$\endgroup\$ – TessellatingHeckler Jul 12 '16 at 0:50
  • \$\begingroup\$ Man, I feel like I've missed out on a lot of tricks having never code golfed before. Its almost like learning to code all over again! \$\endgroup\$ – ThePoShWolf Jul 12 '16 at 15:46

Dyalog APL, 12 bytes


819⌶ is the case folding function

f← because its name is long, we assign it to f

⊢≠f Boolean where text differs from lower-cased text

f¨⍨ use that (1 means uppercase, 0 means lowercase) to fold each letter...

... of the reversed text

Handles non-ASCII according to the Unicode Consortium's rules.


CJam, 22 bytes


Test it here.


Racket, 146 bytes

(λ(s)(build-string(string-length s)(λ(n)((if(char-upper-case?(string-ref s n))char-upcase char-downcase)(list-ref(reverse(string->list s))n)))))

Racket is bad at this whole "golfing" thing.

Shrug As always, any help with shortening this would be much appreciated.


Jolf, 21 bytes

Try it here!



Μid                   (Μ)ap (i)nput with (d)is fucntion:
   ?        =pxHH     (H is current element) if H = lowercase(H)
    &γ._pXiS          and set γ to the uppercase entity in the reversed string
                 pxγ  lowercase γ
                    γ else, return γ
  • \$\begingroup\$ (d)is function... Sacrifice spelling for the sake of golf! \$\endgroup\$ – Steven H. Jul 6 '16 at 22:14

Perl 6, 29 bytes

$_=get;put .flip.samecase($_)

C#, 86 85 bytes


A C# lambda where the input and the output is a string. You can try it on .NetFiddle.

I am struggling to understand why I cant achieve to convert char.ToLower(c) to c+32. I hope to fix it!

12 bytes saved thanks to @PeterTaylor (c|32 to add 32 to the ascii value of c and c&~32 to substract 32). The result would be 72 bytes (but can fail on non alpha char).

  • 1
    \$\begingroup\$ It would be c|32 instead of c+32, but it won't work with non-alpha characters. \$\endgroup\$ – Peter Taylor Jul 6 '16 at 16:53
  • \$\begingroup\$ @PeterTaylor It works great! Thank you! \$\endgroup\$ – aloisdg Jul 6 '16 at 17:12

PHP, 128 bytes


I may attempt to optimize this further but I'll just leave it as is for now.

  • \$\begingroup\$ As notices are allowed, there are a few parts you can optimize at. Instead of a for loop, you can do a while loop and set the char to test directly: while($a=ord($s[$i++])). With that, as we use ord() you can test based on the char number: $a<90&&$a>65. However, for the strtoupper and lower you need to correct the index number as in the loop it was already increased, this means: strtolower($l[$i-1]). This should save quite some bytes \$\endgroup\$ – RFSnake Sep 10 '20 at 11:27

Octave, 51 50 bytes



VIM, 46 bytes

It'd be three bytes g~G if we didn't need to read from stdin or write to stdout, but oh well...

vim -es '+normal! g~G' '+%print|q!' /dev/stdin

To test this, run

echo "testString" | vim -es '+normal! g~G' '+%print|q!' /dev/stdin

This is my first submission on here, not sure if this kind of submission is acceptable.

  • \$\begingroup\$ Nice, I love golfing in vim! However, this program doesn't actually reverse the string, it just toggles the capitalization. You can reverse the string with :se ri<cr>C<C-r>" but then you'll have to figure how to capitalize the right letters. \$\endgroup\$ – James Jul 7 '16 at 7:03
  • \$\begingroup\$ @DrGreenEggsandIronMan Oh man I completely missed that! Back to the drawing board! \$\endgroup\$ – DoYouEvenCodeBro Jul 7 '16 at 14:09

Javascript (using external library) (224 bytes)

(s)=>{t=_.From(s);var cnt=t.Count();var caps=t.Select(x=>{return x.toUpperCase()===x&&x.toLowerCase()!==x}).ToArray(),i=-1;return t.AggregateRight((a,b)=>{i++;var c=caps[i];return c?a+b.toUpperCase():a+b.toLowerCase()},"");}

Disclaimer: Using a library I wrote to bring C#'s LINQ to Javascript

Image 1

  • \$\begingroup\$ Calling out the person who downvoted this without an explanation. Any reason for that? \$\endgroup\$ – applejacks01 Jul 6 '16 at 21:21
  • \$\begingroup\$ It's likely that they wanted you to count the library as well, although using an external library is fully within the boundaries of standard policy. \$\endgroup\$ – Addison Crump Jul 7 '16 at 2:02
  • 1
    \$\begingroup\$ I'm not downvoter, but If you are using an external library, at least mention the name in your answer, and for an obscure library, please provide a link to the repository. \$\endgroup\$ – n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Jul 8 '16 at 9:51

Sed, 113 + 1 = 114 bytes

Why? Because it's fun to use the wrong tool to do things :P

Usage: Run sed -rf file, enter text and press Ctrl + D (send EOF).




s/[A-Z]/\a\l&/g #Prepend all upper-case letters with a 
                #BEL ASCII character and make them lowercase
s/^.*$/\f&\v/   #Wrap text between a from feed (\f) and a vertical tab (\v)
                #These are used as markers

:x #Define a label named x

s/\f\a/\a\f/;s/\a\v/\v\a/ #Move BEL characters outside of the boundary, so they're not moved later
s/\f(.)(.*)(.)\v/\3\2\1/  #This part does the switching itself
                          #It grabs a character preceded by a form feed and another 
                          #one followed by a vertical tab and swaps them, while keeping the text in-between
                          #and replaces the marker \f and \v

tx             #Conditional jump (t) to label x
               #Jumps to the label x if the last substitution (s command) was successful 
s/\f|\v//g     #Delete markers
s/\a(.)/\u\1/g #Make letters preceded by a BEL upper-case

Java 7, 221 217 180 bytes

void c(char[]s){int x=0,y=s.length-1;for(char t;x<y;s[x]=s(t,s[y]),s[y]=s(s[y],t),x++,y--)t=s[x];}char s(char a,char b){return(char)(64<a&a<91?96<b&b<123?b-32:b:64<b&b<91?b+32:b);}

Loads of bytes saved thanks to @LeakuNun's approach.

Ungolfed & test cases:

Try it here.

class Main{
  void c(char[] s){
    int x = 0,
        y = s.length-1;
    for(char t; x < y; s[x] = s(t, s[y]),
                       s[y] = s(s[y], t),
       t = s[x];

  char s(char a, char b){
    return (char)(64 < a & a < 91
                    ? 96 < b & b < 123
                        ? b-32
                        : b
                    : 64 < b & b < 91
                        ? b+32
                        : b);

  public static void main(String[] a){
    print("Hello, Midnightas");
  static void print(String s){
    char[] t = s.toCharArray();


SathginDim ,olleh
  • \$\begingroup\$ You can input and output char[]. \$\endgroup\$ – Leaky Nun Jul 8 '16 at 19:19
  • \$\begingroup\$ @LeakyNun Actually I (believe I) can't in less amount of bytes. It would allow the removal of String a=""; and changed o+= to 0[i]= to save bytes, but Java doesn't have a character .toUpperCase() / .toLowerCase() method, and converting from char to String, use upper/lower method, and then back to char again would require (a lot) more bytes. But feel free to fork the linked ideone and come up with something to make char[] work in less bytes. \$\endgroup\$ – Kevin Cruijssen Jul 8 '16 at 20:41
  • 1
    \$\begingroup\$ 180 bytes that can be golfed further (by not modifying it in place). \$\endgroup\$ – Leaky Nun Jul 9 '16 at 3:02

05AB1E, 9 bytes


Try it online!


          # Push input and input reversed
 l         # lowercase reversed input
  s        # swap to normal input
   €.u     # map is_upper
      ÅÏ   # where this is true,
           # apply to the reversed input:
        u  # uppercase

Your Answer

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