CJam, 44 42 40 byte
qN+ee_{Xa/~\+XW=eu__el=!\'@-*m<Xa+}fXWf=
Output berisi linefeed tambahan.
Uji di sini.
Penjelasan
Alih-alih memindahkan surat melalui string, saya berulang kali menghapus surat, memutar string yang sesuai, dan kemudian memasukkan kembali surat itu. Ada satu tangkapan untuk melakukan ini: kita harus bisa membedakan awal string dari ujung string (yang tidak bisa kita lakukan setelah rotasi sederhana). Itu sebabnya kami menyisipkan linefeed di bagian akhir sebagai penjaga (surat sebelum linefeed adalah akhir dari string, huruf setelah itu adalah awal). Bonus adalah bahwa ini secara otomatis mengembalikan string akhir rotasi yang benar mana linefeed sebenarnya adalah pada akhir 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.
Untuk melihat mengapa ini berakhir di posisi yang tepat, pertimbangkan iterasi terakhir dari hi*bye
contoh. Setelah kami memproses e
, string yang dihitung ada di posisi ini:
[[4 'y] [6 N] [2 '*] [0 'h] [1 'i] [3 'b] [5 'e]]
Pertama, kami membagi linefeed dan menggabungkan bagian-bagian dalam urutan terbalik:
[[2 '*] [0 'h] [1 'i] [3 'b] [5 'e] [4 'y]]
Linefeed sekarang akan berada di awal atau di akhir string ini. Tetapi karena linefeed hanyalah penjaga yang menandai akhir string, ini berarti bahwa karakter sebenarnya dalam urutan yang benar. Sekarang linefeed bukan huruf, sehingga array tidak diputar sama sekali. Jadi, ketika kita menambahkan umpan baris, ia masuk ke tempatnya, dan semuanya dalam urutan yang kami cari:
[[2 '*] [0 'h] [1 'i] [3 'b] [5 'e] [4 'y] [6 N]]
Beberapa hasil tambahan jika seseorang ingin membandingkan kasus pengujian yang lebih lama:
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
Saya suka yang terakhir. :)