This is a simple challenge. Your goal is to unscramble a string by swapping each letter with the next letter of the same case, while leaving non-letter characters unchanged.


Step by step explanation

  1. The first character is a E. We look for the next letter in upper case: it's a C. We swap these characters, which leads to CdoE!.

  2. We advance to the next character: this is a d. We look for the next letter in lower case: it's a o. We swap these characters, which leads to CodE!.

  3. We advance to the next character: this is the d that we've just moved here. We ignore it, because it has already been processed.

  4. We advance to the next character: this is the E that was moved here at step #1. We ignore it, because it has already been processed.

  5. We advance to the next character: this is a !. We ignore it, because it's not a letter.


  • You can assume that the input string is made exclusively of printable ASCII characters, in the range 32 - 126.

  • You may write either a full program or a function, which either prints or returns the result.

  • If the input string contains an odd number of letters, the last remaining letter can't be swapped with another one and should remain in place, no matter its case. The same logic applies if the string contains an even number of letters, but an odd number of uppercase letters and an odd number of lowercase letters.

  • This is code-golf, so the shortest answer in bytes wins. Standard loopholes are forbidden.

Test cases

Input : lLEhW OroLd!
Output: hELlO WorLd!

Input : rpGOZmaimgn uplRzse naC DEoO LdGf
Output: prOGRamming puzZles anD COdE GoLf

Input : eIt uqHKC RBWOO xNf ujPMO SzRE HTL EOvd yAg
Output: tHe quICK BROWN fOx juMPS OvER THE LAzy dOg

Input : NraWgCi: Nsas-eNEiTIsev rNsiTG!!
Output: WarNiNg: Case-sENsITive sTriNG!!

Not-so-random test cases:

Input : (^_^)
Output: (^_^)


Input : hwn oeesd acsp nawyya
Output: who needs caps anyway

Input : SpMycaeIesKyBorekn
Output: MySpaceKeyIsBroken

Input : D's mroyr, Ivam. I'e faardi I act'n od htta.
Output: I'm sorry, Dave. I'm afraid I can't do that.
  • \$\begingroup\$ I assume a similar comment holds if the input contains an even number of letters, but an odd number of uppercase letters and an odd number of lowercase letters. \$\endgroup\$ Feb 4, 2017 at 20:14
  • 15
    \$\begingroup\$ This is a really clever challenge ... I also like the fact that test cases can be made by typing in a lowercase string, randomly changing some of the letters to uppercase, and then running the exact same program that solves the problem! \$\endgroup\$ Feb 4, 2017 at 20:15
  • 2
    \$\begingroup\$ @GregMartin I found out that the problem is its own inverse because when trying a test case I accidentally typed in the output instead of the input :-) \$\endgroup\$
    – Luis Mendo
    Feb 4, 2017 at 20:17
  • \$\begingroup\$ I think you should include test cases with more than one non-letter ASCII character ... I think some implementations could accidentally switch them with each other, when that's not supposed to happen. \$\endgroup\$ Feb 4, 2017 at 20:20
  • 3
    \$\begingroup\$ The tests cases should probably include a string without uppercase letters and a string without any letters at all. \$\endgroup\$
    – Dennis
    Feb 5, 2017 at 2:51

27 Answers 27


Retina, 53 bytes

Not really clever, but a clean and quite readable solution


Try it online!


MATL, 22 bytes


Try it online! Or verify all test cases.

How it works

2:"       % Do the following twice
  ttt     %   Input string (implicit). Push three more copies
  k       %   Convert to lowercase
  <f      %   Indices of characters that had their code point increased by
          %   the lowercase conversion, i.e. that were uppercase letters
  2e      %   Convert to 2-row matrix. This pads a zero in the lower-right 
          %   corner if necessary
  tAZ)    %   Keep only columns that don't contain zeros. Thus if there
          %   was a character that can't be swapped it will be ignored             
  )       %   Get 2-row matrix of characters at those positions
  P       %   Flip vertically. This does the swapping
  5M      %   Push matrix of original indices again
  (       %   Write the swapped characters onto their original positions
  Yo      %   Change case. In the first iteration, this prepares the
          %   string so the second iteration will process the letters that
          %   were originally lowercase. In the second iteration, it
          %   undoes the change of case 
          % End (implicit)
          % Display (implicit)

Jelly, 21 20 19 18 bytes


Try it online!

How it works

nŒlTÇyJịŒsµ⁺  Main link. Argument: s (string)

 Œl           Convert to lowercase.
n             Test for inequality.
   T          Truth; yield all indices of 1's.
    Ç         Call the helper link. Yields [A, B] (pair of lists).
      J       Indices; yield I := [1, ..., len(s)].
     y        Translate; replace the integers of I that occur in A with the
              corresponding integers in B.
        Œs    Swapcase; yield s with swapped case.
       ị      Use the translated index list to index into s with swapped case.
          µ   Combine all links to the left into a chain.
           ⁺   Duplicate the chain, executing it twice.

s2UF,         Helper link. Argument: J (list of indices)

s2            Split J into pairs. If the length is odd, the last list will be
              a singleton list.
  U           Upend; reverse each pair. This is a no-op for singletons lists.
   F          Flatten, concatenating the pairs.
    ,          Pair the previous result with J.

Bash + Unix utilities, 77 62 57 56 54 bytes

sed -r "s/([$1)([^$1*)([$1)/\3\2\1/g"||$0 a-z]|$0 A-Z]

Input in stdin. Output in stdout.

(In this last version, stderr happens to be written to also, but PPCG consensus seems to be that that's OK -- stderr is simply ignored.)

Edit 1: Thanks to @Dennis for 15 bytes! Improvements: (a) Taking input via stdin; (b) combining 2 sed scripts into one; and (c) replacing tr with substitution via bash parameter expansion; (b) and (c) disappeared in Edit 2.

Edit 2: Shorter by 5 additional bytes. Used a function call to replace both (b) and (c) in Edit 1.

Edit 3: One more byte -- passed ] as part of the function arguments.

Edit 4: Replaced the two function calls with calls to the program itself when it has no arguments.

Testbed and sample output:

for x in 'lLEhW OroLd!' 'rpGOZmaimgn uplRzse naC DEoO LdGf' 'eIt uqHKC RBWOO xNf ujPMO SzRE HTL EOvd yAg' 'NraWgCi: Nsas-eNEiTIsev rNsiTG!!' '(^_^)' 'AWCTY HUOS RETP' 'hwn oeesd acsp nawyya' 'SpMycaeIesKyBorekn' "D's mroyr, Ivam. I'e faardi I act'n od htta."; do ./swapping <<<"$x" 2>/dev/null; done

hELlO WorLd!
prOGRamming puzZles anD COdE GoLf
WarNiNg: Case-sENsITive sTriNG!!
who needs caps anyway
I'm sorry, Dave. I'm afraid I can't do that.

ES6, 185 95 bytes


Solution severely shortened with the help of @Neil, @Arnauld and @edc65


f = i =>
  // Get array of characters from input string
  (o = [...i])
    .map((c, j) => 
      // Check if it's a text character, otherwise skip it
      /[a-z]/i.test(c) ? 
        // Get last character position for case
        // merged with setting a variable for if the character is lowercase
        // merged with storing the current case character position,  
        // under properties on the array (with keys "true" or "false")
        o[e = c>"Z"] =
          // Check if there exists a character position to switch with
          // merged with storing the current position for quick access
          1/(b=o[e]) ? 
            // This statement will end up returning the Array subset, 
            // which will be falsy in the above conditional since (1/[])==false
              // Switch left character to the right
            // Switch right character to the left
            ,b]=c : 
            // No character exists for case, so return current character position
         // It was not a text character, so do nothing
  // Join array and return as result
  && o.join``;

`lLEhW OroLd!
NraWgCi: Nsas-eNEiTIsev rNsiTG!!
rpGOZmaimgn uplRzse naC DEoO LdGf
hwn oeesd acsp nawyya
D's mroyr, Ivam. I'e faardi I act'n od htta`
  .map(testCase => console.log(f(testCase)));

  • \$\begingroup\$ 6 bytes, the enclosing parens are redundant when we remove the second statement :) Nice. \$\endgroup\$
    – Jan
    Feb 5, 2017 at 15:42
  • 2
    \$\begingroup\$ Please ignore my last comment. Here's the 99: /[a-z]/i.test(c)?o[e=c>"Z"]=1/(b=o[e])?[o[b],o[j]]=[c,o[b]]:j:0 \$\endgroup\$
    – Arnauld
    Feb 5, 2017 at 16:06
  • 2
    \$\begingroup\$ [o[b],o[j]]=[c,o[b]] could be o[o[j]=o[b],b]=c \$\endgroup\$
    – edc65
    Feb 5, 2017 at 17:27
  • \$\begingroup\$ The real masterstroke here is using true and false as indexes for an array \$\endgroup\$
    – edc65
    Feb 5, 2017 at 17:29
  • \$\begingroup\$ Thanks guys, down to 95 now. It starts becoming really hard to document the solution in a way that makes sense. XD @edc65 they're stored as properties on the array object, not indexes. Yeah Arnauld figured out that they were being stored on the character array, but the reuse of the object was more of a lucky accident I think which came from a separate suggestion. Initially it was stored on a separate object which of course was completely unnecessary for the scope of the challenge. \$\endgroup\$
    – Jan
    Feb 5, 2017 at 18:31

Python, 82 bytes

lambda s:S(r.lower(),t,S(r,t,s))
import re

Try it online!

  • \$\begingroup\$ how does it work? is the lambda even called? \$\endgroup\$ Feb 5, 2017 at 8:37
  • \$\begingroup\$ The lambda is the actual (function) submission. Everything else is just accompanying code that has to be executed before the lambda is called. \$\endgroup\$
    – Dennis
    Feb 5, 2017 at 8:39

QBasic, 229 bytes

FOR i=1TO LEN(s$)
IF u THEN MID$(s$,u,1)=c$:MID$(s$,i,1)=u$
IF l THEN MID$(s$,l,1)=c$:MID$(s$,i,1)=l$


We loop through the input string. When we encounter an uppercase letter, we store it and its position. The second time we encounter an uppercase letter, we use those stored values to swap it with the previous one. Same for lowercase.

(I was about to post a rather longer version that used an array, because I thought that QBasic strings were immutable. Then I stumbled across the fact that MID$(strng$, index, length) = replacement$ works just fine. Live and learn.)

Ungolfed + commented


FOR i = 1 TO LEN(text$)
  char$ = MID$(text$, i, 1)
  IF "A" <= char$ AND "Z" >= char$ THEN
    ' Uppercase
    IF upperIndex = 0 THEN
      ' This is the first of a pair of uppercase letters
      ' Store the letter and its index for later
      upperLetter$ = char$
      upperIndex = i
      ' This is the second of a pair of uppercase letters
      ' Put it at the position of the previous uppercase letter
      ' and put that letter at this letter's position
      MID$(text$, upperIndex, 1) = char$
      MID$(text$, i, 1) = upperLetter$
      upperIndex = 0
    END IF
  ELSEIF "a" <= char$ AND "z" >= char$ THEN
    ' Lowercase
    IF lowerIndex = 0 THEN
      ' This is the first of a pair of lowercase letters
      ' Store the letter and its index for later
      lowerLetter$ = char$
      lowerIndex = i
      ' This is the second of a pair of lowercase letters
      ' Put it at the position of the previous lowercase letter
      ' and put that letter at this letter's position
      MID$(text$, lowerIndex, 1) = char$
      MID$(text$, i, 1) = lowerLetter$
      lowerIndex = 0
    END IF

PRINT text$

C++11 (GCC), 154 149 bytes

[](std::string s){int*p,u,l=u=-1;for(auto&c:s)(c|32)-97<26U?p=&(c&32?u:l),~*p?(std::swap(c,s[*p]),*p=-1):*p=&c-&s[0]:0;return s;}
  • 1
    \$\begingroup\$ You should either also #include<string> or switch to C++14 and declare a generic lambda [](auto s) and assume s to be of std::string. Also, declaring [](auto&s) saves you from returning the string as modifying input arguments to serve as output is allowed. \$\endgroup\$
    – Karl Napf
    Feb 13, 2017 at 12:28

Qbasic, 436 408 bytes

LINE INPUT a$:b=len(a$):FOR a=1TO b:t$=MID$(a$,a,1)
ELSE b$=b$+t$
FOR x=1TO b STEP 2:g$=g$+MID$(u$,x+1,1)+MID$(u$,x,1):h$=h$+MID$(l$,x+1,1)+MID$(l$,x,1):NEXT
FOR x=1TO b:t$=MID$(b$,x,1)
ELSEIF"L"=t$THEN l=l+1:z$=z$+MID$(h$,l,1)
ELSE z$=z$+t$

Saved one byte thanks to DLosc. Saved several more by changing handling of non-letter chars.

This basically consists of three parts:

  • Splitting the input into 3 strings (Uppercase, Lowercase, and a map (also holding the other chars))
  • Flipping the uppercase and lowercase letters
  • Using the map to (re)construct the output.

A more detailed explanation (note that this is of an earlier version of the code, but the principle still applies):

' --- Part I: Reading the input
'This FOR loop takes one character at a time
b=len(a$):FOR a=1TO b
' And checks in what category the character belongs
t$=MID$(a$,a,1):SELECT CASE t$
' For each group, char t$ is added to that group (u$ for uppercase, 
' l$ for lowercase. The map in b$ is updated with a U or L on this index,
' or with the non-letter char t$.
CASE ELSE:b$=b$+t$

' --- Part II: Swapping within case-groups
' Loop through u$ and l$ twp chars at a time, and add those chunks in reverse order
' to g$ and h$. Because mid$ doesn't fail past the end of a string (but returns ""), 
' this automatically compensates for odd-length groups.
FOR x=1TO b STEP 2:g$=g$+MID$(u$,x+1,1)+MID$(u$,x,1):h$=h$+MID$(l$,x+1,1)+MID$(l$,x,1):NEXT

' --- Part III: Read the map to put it all back together
FOR x=1TO b:t$=MID$(b$,x,1)
' See what group was in this spot, then read the next char from the flipped string.
' This keeps an index on those strings for the next lookup.
ELSEIF t$="L"THEN l=l+1:z$=z$+MID$(h$,l,1)
' The map contains a non-letter char, just drop that in
ELSE z$=z$+t$
' And finally,display the end result.

Perl 5, 48 + 1 (-p) = 49 bytes

for$p(qw/([a-z]) ([A-Z])/){s/$p(.*?)$p/$3$2$1/g}

Try it online!


PHP, 108 93 83 bytes


Previous version (93 bytes)


Thanks to @user59178 for reminding me that preg_replace() can take arrays of strings as arguments.

The original answer (108 bytes)


The code is wrapped here to fit the available space.
It can be executed from the command line:

$ php -d error_reporting=0 -r '$f=preg_replace;echo$f("/([a-z])([^a-z]*)([a-z])/",$r="$3$2$1",$f("/([A-Z])([^A-Z]*)([A-Z])/",$r,$argv[1]));' 'lLEhW OroLd!'

A 1-byte shorter version is possible on PHP 7 by squeezing the assignment of $f inside its first call:


Both solutions, with test cases and ungolfed versions can be found on Github.

  • 1
    \$\begingroup\$ preg_replace can take an array of replacements to do so you only need one call. In addition it's shorter to use <?= than echo. With these it's simple to get your answer down to 93 bytes. \$\endgroup\$
    – user59178
    Feb 6, 2017 at 18:18
  • \$\begingroup\$ You are right about preg_replace(). I forgot about it. I don't like <?= (in my opinion <? is not part of the language, it is just a marker) and I like to write short one-line programs that can be executed from the command line using php -r. But for the purpose of code golf you are right again. I can save 1 byte using <?=. \$\endgroup\$
    – axiac
    Feb 6, 2017 at 21:14

Mathematica, 96 bytes


A port of Leo's Retina answer, which uses regular expressions.

  • \$\begingroup\$ I'm honestly surprised that mathematica doesn't have a builtin for that, I mean, if "When's Easter sunday", "When's the sunset" and "what is the shape of france" get builtins, this one should too! \$\endgroup\$
    – sagiksp
    Feb 11, 2017 at 15:18

Python 2, 124 bytes

exec"r='';i=0\nfor c in s:r+=c[u(c):]or filter(u,s+s[::-1])[i^1];i+=u(c)\ns=r.swapcase();"*2
print s

Not as short as my regex-based solution, but I think it's still interesting.

Try it online!


Bean, 83 bytes


00000000 26 53 d0 80 d3 d0 80 a0 5d 20 80 0a a1 81 81 00  &SÐ.ÓÐ. ] ..¡...
00000010 23 81 01 20 80 0a a1 81 81 02 23 81 01 a8 db c1  #.. ..¡...#..¨ÛÁ
00000020 ad da dd a9 a8 db de c1 ad da dd aa bf a9 a8 db  .ÚÝ©¨ÛÞÁ.Úݪ¿©¨Û
00000030 c1 ad da dd 29 a4 b3 a4 b2 a4 31 a8 db e1 ad fa  Á.ÚÝ)¤³¤²¤1¨Ûá.ú
00000040 dd a9 a8 db de e1 ad fa dd aa bf a9 a8 db e1 ad  Ý©¨ÛÞá.úݪ¿©¨Ûá.
00000050 fa dd 29                                         úÝ)

Equivalent JavaScript:



Implicitly taking the first line of input unformatted as a (since newlines can't be part of scrambled string), and implicitly outputs unscrambled string by sequentially replacing uppercase, then lowercase pairs.

Try demo here.

Try test suite here.


Ruby, 81 bytes

puts f=->(i,s){i.gsub /([#{s})([^#{s}*)([#{s})/,'\3\2\1'}[f[$*[0],'a-z]'],'A-Z]']

JavaScript (ES6), 80 bytes

Based on Leo's Retina answer.


This works because the only uppercase characters in the code .replace(/([A-Z])([^A-Z]*)([A-Z])/g,'$3$2$1') are A and Z, which are used to describe the character ranges. This is precisely what we need to transform into lowercase in order to process the second pass.

Test cases

let f =


console.log(f("lLEhW OroLd!"));
console.log(f("rpGOZmaimgn uplRzse naC DEoO LdGf"));
console.log(f("eIt uqHKC RBWOO xNf ujPMO SzRE HTL EOvd yAg"));
console.log(f("NraWgCi: Nsas-eNEiTIsev rNsiTG!!"));
console.log(f("AWCTY HUOS RETP"));
console.log(f("hwn oeesd acsp nawyya"));
console.log(f("D's mroyr, Ivam. I'e faardi I act'n od htta."));

  • \$\begingroup\$ Actually, it turns out to be very similar to this Python answer by Dennis. \$\endgroup\$
    – Arnauld
    Feb 5, 2017 at 19:34

ES6 155 - 195 bytes

I know there's already a better answer, but I wanted to try without regex. This one works on punctuation too, but that seems to violate the (^_^) test. In that case I have another c() function, given below.

f=(s)=>{d={};s=[...s];for(i in s){b=s[i];for(j in s)if(i<j&!d[i]&c(s[j])==c(b)){d[j]=1;s[i]=s[j];s[j]=b;break}}return s.join('')}

f("M I'o DaG") //> I'M a GoD
f("(^_^)")     //> )_^^(


f("M I'o DaG") //> I'M a GoD
f("(^_^)")     //> (^_^)


    d={};        //list of indexes already swapped
    s=[...s];        //string to array, stolen from above ES6 answer
    for(i in s){
        b=s[i];        //keep a note of what we are swapping
        for(j in s)        //iterate over the array again
            if( i<j & !d[i] & c(s[j])==c(b) ){
                        //only pay attention after we pass i'th
                        //only swap if this char hasn't been swapped
                        //only swap if both chars in same 'category'
                d[j]=1;        //note that the latter char has been swapped
                break        //avoid swapping on the same 'i' twice
    return s.join('')        //return as string

Perl 6, 56 bytes

{for "A".."Z","a".."z" ->@c {s:g/(@c)(.*?)(@c)/$2$1$0/}}

Takes a string variable as an argument, and modifies it in-place so that after calling the lambda the variable contains the result.

Longer than it would be in Perl, because:

  • The new regex syntax is more verbose, e.g. writing out the character classes would look like <[A..Z]> instead of [A-Z].
  • Regexes are first-class source code parsed at compile time, and a string can only be interpolated into them at run-time if it consists of a self-contained subregex (i.e. you can't interpolate a string into a character class).
  • Explict EVAL, which would allow more flexibility, requires the golf-unfriendly use MONKEY-SEE-NO-EVAL; pragma.

On the plus side, an array in a @ variable can be referenced directly in a regex, and is treated as an alternation.

Perl 6, 65 bytes

{reduce ->$_,@c {S:g/(@c)(.*?)(@c)/$2$1$0/},$_,"A".."Z","a".."z"}

Functional version (outputs the result as the return value of the lambda).


R, 343 Bytes

Terribly clumsy R solution:

f <- function(x) {
        z=data.frame(l=ifelse(y %in% letters,0,ifelse(y %in% LETTERS,1,2)),s=y)
        l <- list(which(z$l==0),which(z$l==1))
        v <- unlist(l)
        for(j in 1:2) for (i in seq(1,ifelse(length(l[[j]])%%2==1,length(l[[j]])-2,length(l[[j]])-1),2)) l[[j]][i:(i+1)] <- rev(l[[j]][i:(i+1)])
        z[v,] <- z[unlist(l),]

f("D's mroyr, Ivam. I'e faardi I act'n od htta.")

# [1] I ' m   s o r r y ,   D a v e .   I ' m   a f r a i d   I   c a n ' t   d o   t h a t .

Python 2, 181 bytes

Much longer than it should be but anyway:

def F(s):
 for l in[i for i,c in enumerate(s)if c.isupper()],[i for i,c in enumerate(s)if c.islower()]:
  for a,b in zip(l[0::2],l[1::2]):s=s[:a]+s[b]+s[a+1:b]+s[a]+s[b+1:]
 print s

This first creates two lists: one of the indices of the uppercase characters and one for the lowercase characters. Each of these lists is looped through in pairs of indices, and the characters at those indices are switched.

I'll golf this down tomorrow, but for now it's time to sleep.


Pip, 28 bytes


Takes input as a command-line argument. Try it online!


This is a regex solution, using the builtin regex variables XL (lowercase letters, `[a-z]`) and XU (uppercase letters, `[A-Z]`).

                              a is 1st cmdline arg; v is -1 (implicit)
Y[XLXU]                       Yank a list containing XL and XU into y
         y.`.*?`.y            Concatenate y, `.*?`, and y itemwise, giving this list:
                              [`[a-z].*?[a-z]`; `[A-Z].*?[A-Z]`]
       aR                     In a, replace matches of each regex in that list...
                  {        }  ... using this callback function:
                   Sa@0a@v     Swap the 0th and -1st characters of the match
                          a    and return the resulting string
                              Print (implicit)

When the second argument to R is a list, the replacements are performed in series; thus, the lowercase replacement and the uppercase replacement don't interfere with each other.


AWK, 121 129 bytes


Try it online! Note: Link has 8 extra bytes to allow multiline input

Usage is fairly typical, but does require a version of AWK that accepts an empty string as the field separator (most versions of gawk but I'm pretty sure the original AWK would fail :( )

It's very straightforward as it simply iterates over each character and checks if it's found one of that case before. If so, it swaps the characters and resets the checked index. On the learning side of things, I'd never used an assignment statement within an assignment statement in AWK before. For some reason it had never come up. :)

I might be able to shave a couple of bytes by saying to assign OFS and FS outside a BEGIN block via command-line assignment or similar, but it's "cleaner" this way.

Adding the TIO link showed me that I had a transcription error that required 8 bytes to fix :( (I left out 0*(U=a):)


Stax, 18 bytes


Run and debug it

The general approach is regex-based.

  • Two times do:
  • Find all matches for [a-z].*?[a-z].
  • Swap the first and last character in matches.
  • Invert case.

R, 223 163 bytes 148 bytes

EDIT: -60 bytes by implementing a for loop

EDIT: -15 bytes from Giuseppe

u=utf8ToInt(scan(,''));for(i in c(65,97)){l=which(u%in%i:(i+25));x=sum(l|1)%/%2;u[l[1:(x*2)]]=u[c(matrix(l,2)[2:1,1:x])]};cat(intToUtf8(u,T),sep="")

Try it online!

Works by testing if character is a lowercase or uppercase, places them in a matrix, inverts the matrix to extract the values in a swapped format. Then output with cat. Try it online struggles with scan(,'') if the code is more than one line, hence the semicolons throughout the single line of code.

  • \$\begingroup\$ I get 168 on your link, but this golf is 163 \$\endgroup\$
    – Giuseppe
    Aug 7, 2019 at 21:28
  • \$\begingroup\$ And this brings it to 162. \$\endgroup\$
    – Giuseppe
    Aug 7, 2019 at 21:30
  • \$\begingroup\$ this probably works; the x fiddling is the clever bit, but getting rid of m=matrix was 4 bytes as well. \$\endgroup\$
    – Giuseppe
    Aug 7, 2019 at 21:37
  • \$\begingroup\$ What about the scan(,'') problem? And reducing the "lLEhW OroLd!" in TIO to scan(,'') or some other way to get input? \$\endgroup\$
    – Sumner18
    Aug 7, 2019 at 21:39
  • 1
    \$\begingroup\$ You missed a couple: tio.run/##Dc5NC4IwGADgv2LC8H1rEA76muzYIRC6GB3Eg6zEwdxibjSofvvy/… \$\endgroup\$
    – Giuseppe
    Aug 7, 2019 at 22:17

C (gcc), 212 206 205 203 bytes

  • Thanks to ceilingcat for golfing six seven nine bytes.
#define I(a,b)if(S[j=i]/a&b/S[i]){for(;S[++j]<a|S[j]>b;);j<l?s[i]=S[j],s[j]=S[i]:0;}

Try it online!

  • \$\begingroup\$ @ceilingcat Thank you. \$\endgroup\$ Aug 6, 2019 at 20:05
  • \$\begingroup\$ @ceilingcat Thank you. \$\endgroup\$ Jun 13, 2020 at 23:11
  • \$\begingroup\$ @ceilingcat Thank you. \$\endgroup\$ Jun 17, 2020 at 21:33

05AB1E, 26 23 bytes


I/O as a list of characters.

Try it online or verify all test cases.


2F                # Loop 2 times:
  Ð               #  Triplicate the current character-list
                  #  (which will use the implicit input-list in the first iteration)
   l              #  Lowercase all letters of the top copy
    ø             #  Zip/transpose the top two lists; pairing them together, and swapping
                  #  rows/columns
     €Ë≠          #  Check for each pair whether they're NOT the same
                  #  (so uppercase characters that have now become lowercase)
  ā               #  Push a list in the range [1, length] (without popping)
   s              #  Swap so the mapped list is at the top again
    ƶ             #  Multiply each 1/0 by its 1-based index
     0K           #  Remove all 0s
       D          #  Duplicate this list of 1-based indices
        2ô        #  Split it into parts of size 2
          í       #  Reverse each part
           ˜      #  Flatten the list of swapped indices
            ‡     #  Transliterate the indices with the swapped indices in [1, length]
             <    #  Decrease each by 1 (because 05AB1E uses 0-based indexing)
              è   #  Index them into the current character-list
               .š #  And swap all cases (lowercase to uppercase, and vice-versa)
                  # (after the loop, the resulting character-list is output implicitly)

Java 7, 117 bytes

String c(String s){String x="([a-z])(.*?)([a-z])",y="$3$2$1";return s.replaceAll(x,y).replaceAll(x.toUpperCase(),y);}

EDIT: Just noticed I have a similar answer as @Leo's Retina answer, even though I've thought about it independently..


String c(final String s) {
  String x = "([a-z])(.*?)([a-z])",
         y = "$3$2$1";
  return s.replaceAll(x, y).replaceAll(x.toUpperCase(), y);

Test code:

Try it here.

class M{
  static String c(String s){String x="([a-z])(.*?)([a-z])",y="$3$2$1";return s.replaceAll(x,y).replaceAll(x.toUpperCase(),y);}

  public static void main(String[] a){
    System.out.println(c("lLEhW OroLd!"));
    System.out.println(c("rpGOZmaimgn uplRzse naC DEoO LdGf"));
    System.out.println(c("eIt uqHKC RBWOO xNf ujPMO SzRE HTL EOvd yAg"));
    System.out.println(c("NraWgCi: Nsas-eNEiTIsev rNsiTG!!"));
    System.out.println(c("AWCTY HUOS RETP"));
    System.out.println(c("hwn oeesd acsp nawyya"));
    System.out.println(c("D's mroyr, Ivam. I'e faardi I act'n od htta."));


hELlO WorLd!
prOGRamming puzZles anD COdE GoLf
WarNiNg: Case-sENsITive sTriNG!!
who needs caps anyway
I'm sorry, Dave. I'm afraid I can't do that.

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.