CJam, 44 42 40 byte
qN+ee_{Xa/~\+XW=eu__el=!\'@-*m<Xa+}fXWf=
L'output contiene un avanzamento riga finale.
Provalo qui.
Spiegazione
Invece di spostare le lettere attraverso la stringa, rimuovo ripetutamente una lettera, ruoto di conseguenza la stringa e quindi reinserisco la lettera. C'è un trucco per farlo: dobbiamo essere in grado di distinguere l'inizio della stringa dalla fine della stringa (cosa che non possiamo dopo una semplice rotazione). Ecco perché inseriamo un avanzamento di riga alla fine come guardia (la lettera prima dell'alimentazione di riga è la fine della stringa, la lettera dopo che è l'inizio). Il vantaggio è che questo restituisce automaticamente la stringa finale alla rotazione corretta in cui l'avanzamento è effettivamente alla fine della stringa.
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.
Per capire perché questo finisce nella giusta posizione, considera l'ultima iterazione hi*bye
dell'esempio. Dopo aver elaborato il e
, la stringa enumerata è in questa posizione:
[[4 'y] [6 N] [2 '*] [0 'h] [1 'i] [3 'b] [5 'e]]
Innanzitutto, ci dividiamo attorno all'alimentazione di linea e concateniamo le parti in ordine inverso:
[[2 '*] [0 'h] [1 'i] [3 'b] [5 'e] [4 'y]]
L'alimentazione di linea ora sarebbe all'inizio o alla fine di questa stringa. Ma poiché il linefeed è solo una guardia che segna la fine della stringa, ciò significa che i personaggi sono effettivamente nell'ordine giusto. Ora il linefeed non è una lettera, quindi l'array non viene ruotato affatto. Pertanto, quando aggiungiamo l'alimentazione di linea, va dove appartiene e tutto è nell'ordine che stiamo cercando:
[[2 '*] [0 'h] [1 'i] [3 'b] [5 'e] [4 'y] [6 N]]
Alcuni risultati aggiuntivi se qualcuno vuole confrontare casi di test più lunghi:
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
Mi piace l'ultimo. :)