brainfuck (178 bytes)
Bahkan jika brainfuck rumit, itu membantu untuk bekerja dengan butir bahasa. Tanyakan kepada diri sendiri, "Apakah saya harus menyimpan nilai ini secara eksplisit di dalam sel?" Anda sering dapat memperoleh kecepatan dan kehebatan dengan melakukan sesuatu yang lebih halus. Dan ketika nilainya adalah indeks array (atau bilangan alami arbitrer), mungkin tidak muat dalam sel. Tentu saja, Anda bisa menerimanya sebagai batasan program Anda. Tetapi merancang program Anda untuk menangani nilai-nilai besar sering kali akan membuatnya lebih baik dengan cara lain.
Seperti biasa, versi kerja pertama saya dua kali lebih lama dari yang seharusnya — 392 byte. Sejumlah modifikasi dan dua atau tiga penulisan ulang utama menghasilkan versi 178 byte yang relatif anggun ini. (Meskipun mengherankan jenis waktu linear hanya 40 byte.)
>+>>>>>,[>+>>,]>+[--[+<<<-]<[[<+>-]<[<[->[<<<+>>>>+<-]<<[>>+>[->]<<[<]
<-]>]>>>+<[[-]<[>+<-]<]>[[>>>]+<<<-<[<<[<<<]>>+>[>>>]<-]<<[<<<]>[>>[>>
>]<+<<[<<<]>-]]+<<<]]+[->>>]>>]>[brainfuck.org>>>]
Nilai input ditempatkan setiap tiga sel: untuk setiap sel (V), ada sel abel (L) (digunakan untuk navigasi) dan satu sel lagi untuk ruang gores (S). Tata letak keseluruhan array adalah
0 1 0 0 0 SVLSVL ... SVL 0 0 0 0 0 0 ...
Awalnya semua sel L diatur ke 1, untuk menandai bagian dari array yang masih perlu disortir. Ketika kita selesai mempartisi subarray, kita membaginya menjadi subarrays yang lebih kecil dengan mengatur sel L pivot menjadi 0, kemudian menemukan sel L paling kanan yang masih 1 dan mempartisi subarray berikutnya. Anehnya, ini semua pembukuan yang kita butuhkan untuk menangani pemrosesan rekursif subarrays dengan benar. Ketika semua sel L telah memusatkan perhatian, seluruh array diurutkan.
Untuk mempartisi subarray, kami menarik nilai paling kanan ke dalam sel S untuk bertindak sebagai pivot, dan membawanya (dan sel V kosong yang sesuai) ke kiri, membandingkannya dengan nilai satu sama lain di subarray dan bertukar sesuai kebutuhan. Pada akhirnya pivot akan ditukar kembali, menggunakan kode swap yang sama (yang menghemat 50 byte atau lebih). Selama mempartisi, dua sel L ekstra disimpan set ke 0, untuk menandai dua sel yang mungkin perlu ditukar satu sama lain; di akhir partisi, 0 kiri akan menyatu dengan 0 di sebelah kiri subarray, dan 0 kanan akan berakhir menandai porosnya. Proses ini juga meninggalkan 1 tambahan di sel L di sebelah kanan subarray; loop utama dimulai dan berakhir di sel ini.
>+>>>>>,[>+>>,]>+[ set up; for each subarray:
--[+<<<-]<[ find the subarray; if it exists:
[<+>-]<[ S=pivot; while pivot is in S:
<[ if not at end of subarray
->[<<<+>>>>+<-] move pivot left (and copy it)
<<[>>+>[->]<<[<]<-]> move value to S and compare with pivot
]>>>+<[[-]<[>+<-]<]>[ if pivot greater then set V=S; else:
[>>>]+<<<-<[<<[<<<]>>+>[>>>]<-] swap smaller value into V
<<[<<<]>[>>[>>>]<+<<[<<<]>-] swap S into its place
]+<<< end else and set S=1 for return path
] subarray done (pivot was swapped in)
]+[->>>]>> end "if subarray exists"; go to right
]>[brainfuck.org>>>] done sorting whole array; output it