brainfuck (178 bajtów)
Nawet jeśli pieprzenie mózgu jest uciążliwe, pomaga pracować z ziarnem języka. Zadaj sobie pytanie „Czy muszę wyraźnie przechowywać tę wartość w komórce?” Często można uzyskać szybkość i zwięzłość, robiąc coś bardziej subtelnego. A gdy wartość jest indeksem tablicowym (lub dowolną liczbą naturalną), może nie zmieścić się w komórce. Oczywiście możesz zaakceptować to jako ograniczenie swojego programu. Ale zaprojektowanie programu do obsługi dużych wartości często poprawi go na inne sposoby.
Jak zwykle moja pierwsza działająca wersja była dwa razy dłuższa niż potrzebna - 392 bajty. Liczne modyfikacje i dwa lub trzy duże przepisywania spowodowały, że ta stosunkowo wdzięczna 178-bajtowa wersja. (Choć zabawnie, sortowanie według czasu liniowego ma tylko 40 bajtów.)
>+>>>>>,[>+>>,]>+[--[+<<<-]<[[<+>-]<[<[->[<<<+>>>>+<-]<<[>>+>[->]<<[<]
<-]>]>>>+<[[-]<[>+<-]<]>[[>>>]+<<<-<[<<[<<<]>>+>[>>>]<-]<<[<<<]>[>>[>>
>]<+<<[<<<]>-]]+<<<]]+[->>>]>>]>[brainfuck.org>>>]
Wartości wejściowe są rozmieszczone co trzy komórki: dla każdej (V) komórki alue jest komórka abel (L) (używana do nawigacji) i jeszcze jedna komórka dla (S) przestrzeni do rysowania. Ogólny układ tablicy to
0 1 0 0 0 SVLSVL ... SVL 0 0 0 0 0 0 ...
Początkowo wszystkie komórki L są ustawione na 1, aby oznaczyć części tablicy, które nadal wymagają sortowania. Kiedy skończymy dzielenie podtablicy, dzielimy ją na mniejsze podgrupy, ustawiając komórkę L jej osi przestawnej na 0, a następnie lokalizujemy skrajnie prawą komórkę L, która wciąż jest 1, i dzielimy tę podtablicę dalej. Dziwne, to wszystko, czego potrzebujemy do prowadzenia księgowości, aby poprawnie obsłużyć rekurencyjne przetwarzanie subarrays. Po wyzerowaniu wszystkich komórek L cała tablica jest sortowana.
Aby podzielić tablicę podrzędną, przeciągamy jej skrajną prawą wartość do komórki S, aby działała jako oś obrotu, i pozostawiamy ją (i odpowiadającą jej pustą komórkę V) w lewo, porównując ją ze sobą w podtablicy i zamieniając w razie potrzeby. Na końcu oś przestawiana jest z powrotem, przy użyciu tego samego kodu wymiany (co oszczędza około 50 bajtów). Podczas dzielenia dwie dodatkowe komórki L są ustawione na 0, aby zaznaczyć dwie komórki, które mogą wymagać wymiany; pod koniec podziału lewe 0 połączy się z 0 po lewej stronie podtablicy, a prawe 0 zakończy się zaznaczeniem jego osi obrotu. Ten proces pozostawia dodatkowo 1 w komórce L na prawo od podtablicy; główna pętla zaczyna się i kończy w tej komórce.
>+>>>>>,[>+>>,]>+[ 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