Zadanie
Napisz program w wybranym języku, który odczyta wiersze wejścia ze standardowego wejścia do EOF, a następnie zapisze je na standardowym wyjściu w ASCIIbetical, podobnie jak program sort
wiersza poleceń. Krótki, niedoceniony przykład w Pythonie to:
import sys
for line in sorted(sys.stdin):
print(line.rstrip('\n'))
Podstępna część
Podobnie jak w przypadku Wojny OS , Twoim celem jest udowodnienie, że twoja ulubiona platforma jest „lepsza”, poprzez celowe uruchomienie programu znacznie wolniej na konkurencyjnej platformie. Na potrzeby tego konkursu „platforma” składa się z dowolnej kombinacji:
- Edytor
- Architektura (x86, Alpha, ARM, MIPS, PowerPC itp.)
- Bitowość (64-bit vs. 32-bit vs. 16-bit)
- Big-versus little-endian
- System operacyjny
- Windows vs. Linux vs. Mac OS itp.
- Różne wersje tego samego systemu operacyjnego
- Implementacja języka
- Różni dostawcy kompilatorów / interpreterów (np. MSVC ++ vs. GCC)
- Różne wersje tego samego kompilatora / interpretera
Chociaż możesz spełnić wymagania, pisząc kod:
#ifndef _WIN32
Sleep(1000);
#endif
Takiej odpowiedzi nie należy oceniać pozytywnie. Celem jest subtelność. Najlepiej byłoby, gdyby kod wyglądał tak, jakby w ogóle nie był zależny od platformy. Jeśli nie mają żadnych #ifdef
oświadczeń (lub warunków opartych na os.name
lub System.Environment.OSVersion
lub cokolwiek), powinny one mieć wiarygodne uzasadnienie (oparte na kłamstwie, oczywiście).
Uwzględnij w swojej odpowiedzi
- Kod
- Twoje „ulubione” i „nieprzychylne” platformy.
- Dane wejściowe do testowania programu.
- Czas działania na każdej platformie dla tych samych danych wejściowych.
- Opis, dlaczego program działa tak wolno na niekorzystnej platformie.
Odpowiedzi:
do
CleverSort
CleverSort to najnowocześniejszy (tj. Nadmiernie skonstruowany i nieoptymalny) dwustopniowy algorytm sortowania ciągów.
W kroku 1 rozpoczyna się od wstępnego sortowania linii wejściowych za pomocą sortowania radix i pierwszych dwóch bajtów każdej linii. Sortowanie Radix jest nieporównywalne i działa bardzo dobrze dla łańcuchów.
W kroku 2 używa sortowania wstawiania na wstępnie posortowanej liście ciągów. Ponieważ lista jest prawie posortowana po kroku 1, sortowanie wstawiania jest dość wydajne w przypadku tego zadania.
Kod
Platformy
Wszyscy wiemy, że maszyny typu big-endian są znacznie wydajniejsze niż ich odpowiedniki typu little-endian. Do testów porównawczych skompilujemy CleverSort z włączonymi optymalizacjami i losowo utworzymy ogromną listę (nieco ponad 100 000 ciągów) 4-bajtowych linii:
Benchmark Big-Endian
Niezbyt brudny.
Znak Little-Endian
Boo, mały Endian! Gwizd!
Opis
Sortowanie za pomocą wstawiania jest naprawdę dość wydajne w przypadku prawie posortowanych list, ale jest okropnie nieskuteczne w przypadku losowo sortowanych list.
Podstępną częścią CleverSort jest makro FIRSTSHORT :
Na maszynach big-endian uporządkowanie leksykograficzne ciągu dwóch 8-bitowych liczb całkowitych lub ich konwersja na 16-bitowe liczby całkowite i uporządkowanie ich później daje takie same wyniki.
Oczywiście jest to możliwe również na maszynach z małym endianem, ale makro powinno być
który działa zgodnie z oczekiwaniami na wszystkich platformach.
Powyższy „test porównawczy big-endian” jest w rzeczywistości wynikiem użycia odpowiedniego makra.
Przy złym makrze i maszynie typu endian lista jest wstępnie sortowana według drugiego znaku każdej linii, co powoduje losowe uporządkowanie z leksykograficznego punktu widzenia. W tym przypadku sortowanie wstawiane zachowuje się bardzo słabo.
źródło
Python 2 vs. Python 3
Oczywiście Python 3 jest o kilka rzędów wielkości szybszy niż Python 2. Weźmy na przykład tę implementację algorytmu Shellsort :
Kod
Reper
Przygotuj wejście testowe. To pochodzi z odpowiedzi Dennisa, ale z mniejszą liczbą słów - Python 2 jest bardzo powolny ...
Python 2
Python 3
Gdzie jest podstępny kod?
Zakładam, że niektórzy czytelnicy mogą sami wytropić oszusta, więc ukryję odpowiedź za pomocą tagu spoiler.
Premia 1:
Premia 2:
źródło
flag
wygląda tylko na zapis, nie możesz go usunąć? Równieżr
wydaje się zbędny, jeśli tak zrobiszif lst[i+h] < lst[i]: ...
. Z drugiej strony, jeśli zachowasz,r
dlaczego dokonujesz wymiany? Nie mogłeś po prostu zrobićlst[i+h] = lst[i]
? Czy to wszystko jest celowe odwrócenie uwagi?