[Question]
  [
Given a string you must move each letter (starting from the first letter) by its position in the alphabet. If you reach the end of the string you must wrap around. Non-letters don't need to be moved.
Example:
`Dog`
`D` is the fourth letter in the alphabet so we move it four spots to the right. After wrapping around, that changes the string to `oDg`. `o` is the 15th letter, (15 mod 3) = 0, so it does not move. `g` is the 7th letter - (7 mod 3) = 1, so the string becomes `goD`.
`hi*bye`
* `h` is the 8th letter, move it 8 spots - `hi*bye` => `i*hbye`
* `i` is the 9th letter, move it 9 spots - `i*hbye` => `*hbiye`
* `b` is the 2nd letter, move it 2 spots - `*hbiye` => `*hiybe`
* `y` is the 25th letter, move it 25 spots - `*hiybe` => `*hibye`
* `e` is the 5th letter, move it 5 spots - `*hibye` => `*hibey`
Non-letters don't need to be moved, but they still take up space.
* `cat` => `tca`
* `F.U.N` => `.F.NU`
* `mississippi` => `msiisppssii`
  
[Answer]
## CJam, ~~44~~ ~~42~~ 40 bytes
```
qN+ee_{Xa/~\+XW=eu__el=!\'@-*m<Xa+}fXWf=
```
Output contains a trailing linefeed.
[Test it here.](http://cjam.aditsu.net/#code=qN%2Bee_%7BXa%2F~%5C%2BXW%3Deu__el%3D!%5C'%40-*m%3CXa%2B%7DfXWf%3D&input=Hello%2C%0AWorld!)
### Explanation
Instead of moving the letters through the string, I repeatedly remove a letter, rotate the string accordingly, and then reinsert the letter. There's one catch for doing this: we need to be able to distinguish the beginning of the string from the end of the string (which we can't after a simple rotation). That's why we insert a linefeed at the end as a guard (letter before the linefeed is the end of the string, letter after it is the beginning). The bonus is that this automatically returns the final string to the correct rotation where the linefeed actually *is* at the end of the string.
```
lN+     e# Read input and append a linefeed.
ee      e# Enumerate the array, so input "bob" would become [[0 'b] [1 'o] [2 'b] [3 N]]
        e# This is so that we can distinguish repeated occurrences of one letter.
_{      e# Duplicate. Then for each element X in the copy...
  Xa/   e# Split the enumerated string around X.
  ~     e# Dump the two halves onto the stack.
  \+    e# Concatenate them in reverse order. This is equivalent to rotating the current
        e# character to the front and then removing it.
  XW=   e# Get the character from X.
  eu    e# Convert to upper case.
  _     e# Duplicate.
  _el=! e# Check that convert to lower case changes the character (to ensure we have a
        e# letter).
  \'@-  e# Swap with the other upper-case copy and subtract '@, turning letters into 1 to
        e# 26 (and everything else into junk).
  *     e# Multiply with whether it's a letter or not to turn said junk into 0 (that means
        e# everything which is not a letter will be moved by 0 places).
  m<    e# Rotate the string to the left that many times.
  Xa+   e# Append X to the rotated string.
}fX
Wf=     e# Extract the character from each pair in the enumerated array.
```
To see why this ends up in the right position, consider the last iteration of the `hi*bye` example. After we've processed the `e`, the enumerated string is in this position:
```
[[4 'y] [6 N] [2 '*] [0 'h] [1 'i] [3 'b] [5 'e]]
```
First, we split around the linefeed and concatenate the parts in reverse order:
```
[[2 '*] [0 'h] [1 'i] [3 'b] [5 'e] [4 'y]]
```
The linefeed would now be either at the beginning or the end of this string. But since the linefeed is just a guard that *marks* the end of the string, this means that the characters are actually in the right order. Now the linefeed is not a letter, so that the array is not rotated at all. Thus, when we append the linefeed, it goes where it belongs, and everything is in the order we're looking for:
```
[[2 '*] [0 'h] [1 'i] [3 'b] [5 'e] [4 'y] [6 N]]
```
Some additional results if someone wants to compare longer test cases:
```
Hello, World!
,W oeHlo!lrld
Programming Puzzles & Code Golf
ago fgliPomomnrr elP& uC dezzsG
The quick brown fox jumps over the lazy dog
t eg chbi ko qfTounyzrj omw epx ueoahs rlvd
abcdefghijklmnopqrstuvwxyz
aqbrcdsetfguhivjwklxmnyozp
zyxwvutsrqponmlkjihgfedcba
abcdefghijklmnopqrstuvwxyz
```
I like that last one. :)
[Answer]
# Ruby 125 ~~130 132 139~~ bytes
```
->q{a=q.chars.map{|c|[c,c=~/[a-z]/i&&c.ord%32]}
while i=a.index{|c,s|s}
c,s=a.delete_at i
a.insert (i+s)%q.size,[c]
end
a*''}
```
Online demo with tests: <http://ideone.com/GYJm2u>
The initial (ungolfed version): <http://ideone.com/gTNvWY>
*Edit:* Big thanks to [manatwork](https://codegolf.stackexchange.com/users/4198/manatwork) for his suggestions!
*Edit 2*: fixed character count (I was initially counting CRLF line endings.)
[Answer]
# Python 3, ~~278~~ ~~275~~ ~~273~~ ~~270~~ ~~260~~ ~~258~~ ~~249~~ ~~248~~ ~~243~~ 238 bytes
I should really golf this down better, but here is my solution, with thanks to [katenkyo](https://codegolf.stackexchange.com/users/41019/katenkyo) for his help with the logic, and to [Cyoce](https://codegolf.stackexchange.com/users/41042/cyoce) and [Mego](https://codegolf.stackexchange.com/users/45941/mego) for their help with the golfing.
**Edit:** At last, I got it down to one comparison statement. WOO! (And yes, I could move that `z=-z` into `a,m=m,a` bit, but that doesn't save bytes and it muddled the code more than I thought was necessary)
**Edit:** Byte count was off.
```
def m(s):
 l=len(s);r=range(l);p=[[i,s[i]]for i in r]
 for i in r:
  if s[i].isalpha():
   a=p[i][0];p[i][0]=m=(a+ord(s[i])%32)%l;z=1
   if a>m:a,m=m,a;z=-z
   for j in r:p[j][0]-=z*(j!=i)*(a<=p[j][0]<=m) 
 return''.join(dict(p).values())
```
**Ungolfed:**
```
def move(string):
 length = len(string)
 places = [[i,string[i]]for i in range(length)]
 for index in range(length):
  char = string[index]
  if char.isalpha():
   a = places[index][0]
   mov = (a + ord(char)%32) % length
   places[index][0] = mov
   for j in range(length):
    k = places[j][0]
    if a <= k <= mov and j!=index:
     places[j][0]-=1
    elif mov <= k <= a and j != index:
     places[j][0]+=1
 return''.join(dict(places).values())
```
[Answer]
# [J](https://www.jsoftware.com), 92 84 bytes
```
{~(g=.i.@#@[)([/:g(]+]-*@-)#@[|g+(={.)*1{])~&;/@([|.@;;/@,.)[:(26&|+52&>)Alpha_j_&i.
```
[Attempt This Online!](https://ato.pxeger.com/run?1=m70wa8FNVUtFK8NYM0UrS3V1LiU99TQFWysFdQUdBQMFKyDW1VNwDvJxW1pakqZrcTOkuk4j3VYvU89B2SFaUyNa3ypdI1Y7VlfLQVcTKFKTrq1hW62nqWVYHatZp2at76ARXaPnYA1k6OhpRltpGJmp1WibGqnZaTrmFGQkxmfFq2XqQc1O1ORKTc7IV0hTUHfTC9XzU4dzkxNLEJzczOJiECooyEQIViCYVZUV5WWlJcVFhQX5ebk52VmZGelpqSnJSYnqEIsWLIDQAA)
*-8 thanks to rdm!*
[Answer]
# [K (ngn/k)](https://codeberg.org/ngn/k), ~~46~~ 45 bytes
-1 byte from @Traws' improvement
```
{x{?[x^z;(#x)!y+x?z;z]}/[;a*27>a:96!_x].&=#x}
```
[Try it online!](https://ngn.codeberg.page/k/#eJxNjr1ugzAURnc/BSFVlVDFliqFqlhJlihjtkyINo5rjBXAFLuVAdFnr3+WXN3lnG85ZTaZ6ZCbjxGvlma9GF7MYcRjMaMck+T1bU+y93TxaQr4vFuaGQCdTU/58NdnZWTwVd7x6loSUWODB9yvixnoPD5KHuOYy2NcOKxEchuYNUklbmwIkhJtjaYk4Ale4NkKeILnS1CNUMp91wk7NEoI1XWWhZ0BApXWncoQovKLcVmXUGlC78zQirScQSob9P3DlBayVShNt9sU1Uxr1qsNZ3rTyF/RcgAie7Y32u0jG+wx9DoTgr20vc7YYI++1wkf7NVDrxseggH4B+Rzbnw=)
A bit complicated to unpack. Takes input as `x`.
* `&=#x` generate two copies of `0..count[input]` (e.g., `(0 1 2 3 4;0 1 2 3 4)`)
* `{...}/[;...].` set up a seeded-reduce, fixing the second (`y`) arg, and passing the pair of ranges as the first (`x`) and third (`z`) args. `x` represents the to-be-shuffled indices of the input, `y` the number of positions to shift each character in the input, and `z` the *initial* position of each character
	+ `a*27>a:96!_x` determine the number of positions to shift each character in the input; non-letters are shifted `0` places, leaving them in the same position
	+ `{?[x^z;(#x)!y+x?z;z]}/` set up a `?[x;indices;values]` splice. each iteration is run on the original input (`x`), a single number of positions to move (`y`), and a single initial position (`z`)
		- `x^z` remove the current item being shifted
		- `(#x)!y+x?z` determine where it should be after being moved (offset by where it is *now* (`x?z`), and with wrap-around `(#x)!`)
		- `z` re-insert the value/index at the correct position
* `{x{...}...}` index back into the original input, and (implicitly) return
]