[Question]
  [
# Challenge Description
Cycle all letters from the first part of the alphabet in one direction, and letters from the second half of the alphabet in the other. Other characters stay in place.
# Examples
1: Hello world
```
Hello_world //Input
Hell     ld //Letters from first half of alphabet
    o wor   //Letters from second half of alphabet
     _      //Other characters
dHel     ll //Cycle first letters
    w oro   //Cycle second letters
     _      //Other characters stay
dHelw_oroll //Solution
```
2: codegolf
```
codegolf
c deg lf
 o   o  
f cde gl
 o   o  
focdeogl
```
3.: empty string
```
(empty string) //Input
(empty string) //Output
```
# Input
String you need to rotate. May be empty. Does not contain newlines.
# Output
Rotated input string, trailing newline allowed  
May be written to the screen or returned by a function.
# Rules
* No loopholes allowed
* This is code-golf, so shortest code in bytes solving the problem wins
* Program must return the correct solution
  
[Answer]
# [Retina](http://github.com/mbuettner/retina), 55 bytes
```
O$i`[a-m](?=.*([a-m]))?
$1
O$i`((?<![n-z].*))?[n-z]
$#1
```
[Try it online!](http://retina.tryitonline.net/#code=TyRpYFthLW1dKD89LiooW2EtbV0pKT8KJDEKTyRpYCgoPzwhW24tel0uKikpP1tuLXpdCiQjMQ&input=SGVsbG9fd29ybGQ)
Uses two sorting stages to rotate the first- and second-half letters separately.
[Answer]
# [05AB1E](http://github.com/Adriandmen/05AB1E), ~~44~~ ~~43~~ 42 [bytes](http://www.cp1252.com/)
```
Ðžn2äø€J2ä©`ŠÃÁUÃÀVv®`yåiY¬?¦VëyåiX¬?¦Uëy?
```
**Explanation**
Generate a list of the letters of the alphabet of both cases. `['Aa','Bb', ..., 'Zz']`  
```
Ðžn2äø€J
```
Split into 2 parts and store a copy in the register.
```
2ä©
```
Extract the letters from the input that are a part of the 1st half of the alphabet, rotate it and store in **X**.
```
`ŠÃÁU
```
Extract the letters from the input that are a part of the 2nd half of the alphabet, rotate it and store in **Y**.
```
ÃÀV
```
Main loop
```
v                         # for each char in input
 ®`                       # push the lists of first and second half of the alphabet
   yåi                    # if current char is part of the 2nd half of the alphabet
      Y¬?                 # push the first char of the rotated letters in Y
         ¦V               # and remove that char from Y
           ëyåi           # else if current char is part of the 1st half of the alphabet
               X¬?        # push the first char of the rotated letters in X
                  ¦U      # and remove that char from X
                    ëy?   # else print the current char
```
[Try it online!](http://05ab1e.tryitonline.net/#code=w5DFvm4yw6TDuOKCrEoyw6TCqWDFoMODw4FVw4PDgFZ2wq5gecOlaVnCrD_CplbDq3nDpWlYwqw_wqZVw6t5Pw&input=SGVsbG9fd29ybGQ)
**Note:** The leading `Ð` can be omitted in [2sable](https://github.com/Adriandmen/2sable) for a **41** byte solution.
[Answer]
# Javascript (ES6), ~~155~~ ~~142~~ 138 bytes
```
s=>(a=[],b=[],S=s,R=m=>s=s.replace(/[a-z]/gi,c=>(c<'N'|c<'n'&c>'Z'?a:b)[m](c)),R`push`,a.unshift(a.pop(b.push(b.shift()))),s=S,R`shift`,s)
```
*Edit: saved ~~3~~ 4 bytes by using `unshift()` (inspired by edc65's answer)*
### How it works
The `R` function takes an array method as its parameter `m`:
```
R = m => s = s.replace(/[a-z]/gi, c => (c < 'N' | c < 'n' & c > 'Z' ? a : b)[m](c))
```
It is first used with the `push` method to store extracted characters in `a[]` (first half of alphabet) and `b[]` (second half of alphabet). Once these arrays have been rotated, `R()` is called a second time with the `shift` method to inject the new characters in the final string.
Hence the slightly unusual syntax: `R`push``  and `R`shift`` .
### Demo
```
let f =
s=>(a=[],b=[],S=s,R=m=>s=s.replace(/[a-z]/gi,c=>(c<'N'|c<'n'&c>'Z'?a:b)[m](c)),R`push`,a.unshift(a.pop(b.push(b.shift()))),s=S,R`shift`,s)
console.log("Hello_world", "=>", f("Hello_world"));
console.log("codegolf", "=>", f("codegolf"));
console.log("HELLO_WORLD", "=>", f("HELLO_WORLD"));
```
[Answer]
# [CJam](http://sourceforge.net/projects/cjam/), 41 bytes
```
lee_{'N,_el^:A&},_1m>er_{ADf+&},_1m<erWf=
```
[Try it online!](http://cjam.tryitonline.net/#code=bGVlX3snTixfZWxeOkEmfSxfMW0-ZXJfe0FEZismfSxfMW08ZXJXZj0&input=SGVsbG9fd29ybGQ)
Uses a similar approach to my [vowel shuffling answer](https://codegolf.stackexchange.com/a/91766/8478).
[Answer]
# Python, 211 Bytes
```
x=input()
y=lambda i:'`'<i.lower()<'n'
z=lambda i:'m'<i.lower()<'{'
u=filter(y,x)
d=filter(z,x)
r=l=""
for i in x:
 if y(i):r+=u[-1];u=[i]
 else:r+=i
for i in r[::-1]:
 if z(i):l=d[0]+l;d=[i]
 else:l=i+l
print l
```
Best i could do. Takes the string from STDIN and prints the result to STDOUT.
### alternative with 204 Bytes, but unfortunatly prints a newline after each char:
```
x=input()
y=lambda i:'`'<i.lower()<'n'
z=lambda i:'m'<i.lower()<'{'
f=filter
u=f(y,x)
d=f(z,x)
r=l=""
for i in x[::-1]:
 if z(i):l=d[0]+l;d=[i]
 else:l=i+l
for i in l:
 a=i
 if y(i):a=u[-1];u=[i]
 print a
```
[Answer]
# [MATL](http://github.com/lmendo/MATL), 29 bytes
```
FT"ttk2Y213:lM@*+)m)1_@^YS9M(
```
[Try it online!](http://matl.tryitonline.net/#code=RlQidHRrMlkyMTM6bE1AKispbSkxX0BeWVM5TSg&input=J0hlbGxvX3dvcmxkJw)
### Explanation
```
FT        % Push arrray [0 1]
"         % For each
  t       %   Duplicate. Takes input string implicitly in the first iteration
  tk      %   Duplicate and convert to lower case
  2Y2     %   Predefined string: 'ab...yz'
  13:     %   Generate vector [1 2 ... 13]
  lM      %   Push 13 again
  @*      %   Multiply by 0 (first iteration) or 1 (second): gives 0 or 13
  +       %   Add: this leaves [1 2 ... 13] as is in the first iteration and
          %   transforms it into [14 15 ... 26] in the second
  )       %   Index: get those letters from the string 'ab...yz'
  m       %   Ismember: logical index of elements of the input that are in 
          %   that half of the alphabet
  )       %   Apply index to obtain those elements from the input
  1_@^    %   -1 raised to 0 (first iteration) or 1 (second), i.e. 1 or -1
  YS      %   Circular shift by 1 or -1 respectively
  9M      %   Push the logical index of affected input elements again
  (       %   Assign: put the shifted chars in their original positions
          % End for each. Implicitly display
```
[Answer]
# Python 2, 149 bytes
```
s=input();g=lambda(a,b):lambda c:a<c.lower()<b
for f in g('`n'),g('m{'):
 t='';u=filter(f,s)[-1:]
 for c in s:
  if f(c):c,u=u,c
  t=c+t
 s=t
print s
```
[Answer]
# JavaScript (ES6), 144
Using `parseInt` base 36 to separate first half, second half and other. For any character `c`, I evaluate `y=parseInt(c,36)` so that
* `c '0'..'9' -> y 0..9`
* `c 'a'..'m' or 'A'..'M' -> y 10..22`
* `c 'n'..'z' or 'N'..'Z' -> y 23..35`
* `c any other -> y NaN`
So `y=parseInt(c,36), x=(y>22)+(y>9)` gives `x==1` for first half, `x==2` for second half and `x==0` for any other (as `NaN` > any number is false)
First step: the input string is mapped to an array of 0,1 or 2. Meanwhile all the string characters ar added to 3 arrays. At the end of this first step the array 1 and 2 are rotated in opposite directions.
Second step: the mapped array is scanned, rebuilding an output string taking each character from the 3 temporary arrays.
```
s=>[...s].map(c=>a[y=parseInt(c,36),x=(y>22)+(y>9)].push(c)&&x,a=[[],p=[],q=[]]).map(x=>a[x].shift(),p.unshift(p.pop(q.push(q.shift())))).join``
```
*Less golfed*
```
s=>[...s].map(
  c => a[ y = parseInt(c, 36), x=(y > 22) + (y > 9)].push(c) 
       && x,
  a = [ [], p=[], q=[] ]
).map(
  x => a[x].shift(),  // get the output char from the right temp array
  p.unshift(p.pop()), // rotate p
  q.push(q.shift())   // rotate q opposite direction
).join``
```
**Test**
```
f=
s=>[...s].map(c=>a[y=parseInt(c,36),x=(y>22)+(y>9)].push(c)&&x,a=[[],p=[],q=[]]).map(x=>a[x].shift(),p.unshift(p.pop()),q.push(q.shift())).join``
function update() {
  O.textContent=f(I.value);
}
update()
```
```
<input id=I oninput='update()' value='Hello, world'>
<pre id=O></pre>
```
[Answer]
# Perl. 53 bytes
Includes +1 for `-p`
Run with the input on STDIN:
```
drotate.pl <<< "Hello_world"
```
`drotate.pl`:
```
#!/usr/bin/perl -p
s%[n-z]%(//g,//g)[1]%ieg;@F=/[a-m]/gi;s//$F[-$.--]/g
```
[Answer]
# Python, ~~142~~ 133 bytes
A better variation on the theme:
```
import re
def u(s,p):x=re.split('(?i)([%s])'%p,s);x[1::2]=x[3::2]+x[1:2];return ''.join(x)
v=lambda s:u(u(s[::-1],'A-M')[::-1],'N-Z')
```
## ungolfed:
```
import re
def u(s,p):
    x = re.split('(?i)([%s])'%p,s)  # split returns a list with matches at the odd indices
    x[1::2] = x[3::2]+x[1:2]
    return ''.join(x)
def v(s):
  w = u(s[::-1],'A-M')
  return u(w[::-1],'N-Z')
```
## prior solution:
```
import re
def h(s,p):t=re.findall(p,s);t=t[1:]+t[:1];return re.sub(p,lambda _:t.pop(0),s)
f=lambda s:h(h(s[::-1],'[A-Ma-m]')[::-1],'[N-Zn-z]')
```
### ungolfed:
```
import re
def h(s,p):                              # moves matched letters toward front
    t=re.findall(p,s)                    # find all letters in s that match p
    t=t[1:]+t[:1]                        # shift the matched letters
    return re.sub(p,lambda _:t.pop(0),s) # replace with shifted letter
def f(s):
    t = h(s[::-1],'[A-Ma-m]')            # move first half letters toward end
    u = h(t[::-1],'[N-Zn-z]')            # move 2nd half letters toward front
    return u
```
[Answer]
## Ruby, 89 bytes
```
f=->n,q,s{b=s.scan(q).rotate n;s.gsub(q){b.shift}}
puts f[1,/[n-z]/i,f[-1,/[a-m]/i,gets]]
```
[Answer]
# PHP, 189 bytes
Quite hard to golf... Here is my proposal:
```
for($p=preg_replace,$b=$p('#[^a-m]#i','',$a=$argv[1]),$i=strlen($b)-1,$b.=$b,$c=$p('#[^n-z]#i','',$a),$c.=$c;($d=$a[$k++])!=='';)echo strpos(z.$b,$d)?$b[$i++]:(strpos(a.$c,$d)?$c[++$j]:$d);
```
]