CJam, 44 42 40 octets
qN+ee_{Xa/~\+XW=eu__el=!\'@-*m<Xa+}fXWf=
La sortie contient un retour à la ligne final.
Testez-le ici.
Explication
Au lieu de déplacer les lettres dans la chaîne, j'enlève à plusieurs reprises une lettre, la fais pivoter en conséquence, puis je réinsère la lettre. Il y a un problème pour cela: nous devons pouvoir distinguer le début de la chaîne de la fin de la chaîne (ce qui n'est pas possible après une simple rotation). C'est pourquoi nous insérons un saut de ligne à la fin en guise de garde (lettre avant le saut de ligne est la fin de la chaîne, lettre après le début). Le bonus est que cela ramène automatiquement la dernière chaîne à la bonne rotation où le saut de ligne se situe réellement à la fin de la chaîne.
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.
Pour voir pourquoi cela aboutit dans la bonne position, considérons la dernière itération de l' hi*bye
exemple. Après avoir traité le e
, la chaîne énumérée se trouve dans cette position:
[[4 'y] [6 N] [2 '*] [0 'h] [1 'i] [3 'b] [5 'e]]
Tout d'abord, nous divisons autour du saut de ligne et concaténons les parties dans l'ordre inverse:
[[2 '*] [0 'h] [1 'i] [3 'b] [5 'e] [4 'y]]
Le saut de ligne serait maintenant soit au début ou à la fin de cette chaîne. Mais comme le saut de ligne est juste un garde qui marque la fin de la chaîne, cela signifie que les caractères sont en fait dans le bon ordre. Maintenant, le saut de ligne n'est pas une lettre, de sorte que le tableau ne subit aucune rotation. Ainsi, lorsque nous ajoutons le saut de ligne, il se place là où il se trouve et tout est dans l'ordre que nous recherchons:
[[2 '*] [0 'h] [1 'i] [3 'b] [5 'e] [4 'y] [6 N]]
Quelques résultats supplémentaires si quelqu'un souhaite comparer des cas de test plus longs:
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
J'aime ce dernier. :)