Unscramble those case-(very)-sensitive strings

Goal

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.

Rules

• 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 : AWCTY HUOS RETP

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.
• 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. – Greg Martin Feb 4 '17 at 20:14
• 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! – Greg Martin Feb 4 '17 at 20:15
• @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 :-) – Luis Mendo Feb 4 '17 at 20:17
• 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. – Greg Martin Feb 4 '17 at 20:20
• The tests cases should probably include a string without uppercase letters and a string without any letters at all. – Dennis Feb 5 '17 at 2:51

Jelly, 212019 18 bytes

s2UF,
nŒlTÇyJịŒsµ⁺

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.

Retina, 53 bytes

Not really clever, but a clean and quite readable solution

([a-z])(.*?)([a-z])
$3$2$1 ([A-Z])(.*?)([A-Z])$3$2$1

Try it online!

MATL, 22 bytes

2:"tttk<f2etAZ))P5M(Yo

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)

Bash + Unix utilities, 77625756 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
tHe quICK BROWN fOx juMPS OvER THE LAzy dOg
WarNiNg: Case-sENsITive sTriNG!!
(^_^)
who needs caps anyway
MySpaceKeyIsBroken
I'm sorry, Dave. I'm afraid I can't do that.

ES6, 185 95 bytes

i=>(o=[...i]).map((c,j)=>/[a-z]/i.test(c)?o[e=c>"Z"]=1/(b=o[e])?o[o[j]=o[b],b]=c:j:0)&&o.join

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

Explanation

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
o[
// Switch left character to the right
o[j]=o[b]
// Switch right character to the left
,b]=c :
// No character exists for case, so return current character position
j
// It was not a text character, so do nothing
:0
)
// Join array and return as result
&& o.join;

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

• 6 bytes, the enclosing parens are redundant when we remove the second statement :) Nice. – Jan Feb 5 '17 at 15:42
• 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 – Arnauld Feb 5 '17 at 16:06
• [o[b],o[j]]=[c,o[b]] could be o[o[j]=o[b],b]=c – edc65 Feb 5 '17 at 17:27
• The real masterstroke here is using true and false as indexes for an array – edc65 Feb 5 '17 at 17:29
• 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. – Jan Feb 5 '17 at 18:31

Python, 82 bytes

lambda s:S(r.lower(),t,S(r,t,s))
import re
S=re.sub
r='([A-Z])(.*?)'*2
t=r'\3\2\1'

Try it online!

• how does it work? is the lambda even called? – Display Name Feb 5 '17 at 8:37
• The lambda is the actual (function) submission. Everything else is just accompanying code that has to be executed before the lambda is called. – Dennis Feb 5 '17 at 8:39

QBasic, 229 bytes

LINE INPUT s$FOR i=1TO LEN(s$)
c$=MID$(s$,i,1) IF"@"<c$AND"[">c$THEN IF u THEN MID$(s$,u,1)=c$:MID$(s$,i,1)=u$u=-i*(u=0) u$=c$ELSEIF""<c$AND"{">c$THEN IF l THEN MID$(s$,l,1)=c$:MID$(s$,i,1)=l$l=-i*(l=0) l$=c$END IF NEXT ?s$

Strategy

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 LINE INPUT text$

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
ELSE
' 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
ELSE
' 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
END IF
NEXT i

PRINT text$C++11 (GCC), 154 149 bytes #include<algorithm> [](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;} • 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. – Karl Napf Feb 13 '17 at 12:28 Qbasic, 436 408 bytes LINE INPUT a$:b=len(a$):FOR a=1TO b:t$=MID$(a$,a,1)
IF"@"<t$AND"[">t$THEN
b$=b$+"U":u$=u$+t$ELSEIF""<t$AND"{">t$THEN b$=b$+"L":l$=l$+t$
ELSE b$=b$+t$END IF:NEXT 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)
IF"U"=t$THEN u=u+1:z$=z$+MID$(g$,u,1) ELSEIF"L"=t$THEN l=l+1:z$=z$+MID$(h$,l,1)
ELSE z$=z$+t$END IF:NEXT:?z$

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
LINE INPUT a$'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"A"TO"Z":b$=b$+"U":u$=u$+t$
CASE"a"TO"z":b$=b$+"L":l$=l$+t$CASE ELSE:b$=b$+t$
END SELECT:NEXT

' --- 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.
IF t$="U"THEN u=u+1:z$=z$+MID$(g$,u,1) 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. END IF:NEXT:?z$

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, 10893 83 bytes

<?=preg_replace([$a="/([a-z])([^a-z]*)([a-z])/",strtoupper($a)],"$3$2$1",$argv[1]);

Previous version (93 bytes)

<?=preg_replace(["/([a-z])([^a-z]*)([a-z])/","/([A-Z])([^A-Z]*)([A-Z])/"],"$3$2$1",$argv[1]);

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

$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])); 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:

echo($f=preg_replace)("/([a-z])([^a-z]*)([a-z])/",$r="$3$2$1",$f("/([A-Z])([^A-Z]*)([A-Z])/",$r,$argv[1]));

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

• 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. – user59178 Feb 6 '17 at 18:18
• 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 <?=. – axiac Feb 6 '17 at 21:14

Mathematica, 96 bytes

JavaScript (ES6), 80 bytes

s=>eval("s"+(r=".replace(/([A-Z])([^A-Z]*)([A-Z])/g,'$3$2$1')")+r.toLowerCase()) 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.

let f =

s=>eval("s"+(r=".replace(/([A-Z])([^A-Z]*)([A-Z])/g,'$3$2$1')")+r.toLowerCase()) 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("(^_^)")); console.log(f("AWCTY HUOS RETP")); console.log(f("hwn oeesd acsp nawyya")); console.log(f("SpMycaeIesKyBorekn")); console.log(f("D's mroyr, Ivam. I'e faardi I act'n od htta.")); • Actually, it turns out to be very similar to this Python answer by Dennis. – Arnauld Feb 5 '17 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('')} c=c=>~(c.charCodeAt()/32) f("M I'o DaG") //> I'M a GoD f("(^_^)") //> )_^^( c=c=>((c!=c.toUpperCase())<<1|c!=c.toLowerCase())||c.charCodeAt() f("M I'o DaG") //> I'M a GoD f("(^_^)") //> (^_^) Explanation f=(s)=>{ 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 s[i]=s[j]; s[j]=b; 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.

{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) { y=unlist(strsplit(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),] return(z$s)
}

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

Y[XLXU]aRy..*?.y{Sa@0a@va}

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

Explanation

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

BEGIN{FS=OFS=""}{for(a=1;a<=NF;a++){if($a~/[A-Z]/?U>0?p=U+(U=0):0*(U=a):$a~/[a-z]/?L>0?p=L+(L=0):0*(L=a):0>0){t=$a;$a=$p;$p=t}}}1

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

âß:}\]ó☺æ■jφ╛jz/Φi

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, 223163 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.

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

C (gcc), 212206205 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;}
i,j,l;f(char*S){char*s=calloc(l=-~strlen(S),1);for(i=~0;++i<strlen(S);)if(!s[i]){s[i]=S[i];I(65,90)I(97,'z')}puts(s);}

Try it online!

• @ceilingcat Thank you. – Jonathan Frech Aug 6 '19 at 20:05
• @ceilingcat Thank you. – Jonathan Frech Jun 13 '20 at 23:11
• @ceilingcat Thank you. – Jonathan Frech Jun 17 '20 at 21:33

05AB1E, 26 23 bytes

2FÐlø€Ë≠āsƶ0KD2ôí˜‡<è.š

I/O as a list of characters.

Explanation:

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.. Ungolfed: 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("(^_^)"));
System.out.println(c("AWCTY HUOS RETP"));
System.out.println(c("hwn oeesd acsp nawyya"));
System.out.println(c("SpMycaeIesKyBorekn"));
System.out.println(c("D's mroyr, Ivam. I'e faardi I act'n od htta."));
}
}

Output:

hELlO WorLd!
prOGRamming puzZles anD COdE GoLf
tHe quICK BROWN fOx juMPS OvER THE LAzy dOg
WarNiNg: Case-sENsITive sTriNG!!
(^_^)