La tâche
Écrivez un programme, dans la langue de votre choix, qui lit les lignes d'entrée de l'entrée standard jusqu'à EOF, puis les écrit sur la sortie standard dans un ordre ASCIIbétique, similaire au sort
programme de ligne de commande. Un exemple court et non sournois en Python est:
import sys
for line in sorted(sys.stdin):
print(line.rstrip('\n'))
La partie sournoise
Semblable à The OS War , votre objectif est de prouver que votre plate-forme préférée est «meilleure», en faisant délibérément fonctionner votre programme beaucoup plus lentement sur une plate-forme concurrente. Pour les besoins de ce concours, une «plate-forme» comprend toute combinaison de:
- Processeur
- Architecture (x86, Alpha, ARM, MIPS, PowerPC, etc.)
- Témoin (64 bits contre 32 bits contre 16 bits)
- Gros ou petit endian
- Système opérateur
- Windows vs Linux vs Mac OS, etc.
- Différentes versions du même système d'exploitation
- Implémentation du langage
- Différents fournisseurs de compilateurs / interprètes (par exemple, MSVC ++ vs GCC)
- Différentes versions du même compilateur / interprète
Bien que vous puissiez répondre aux exigences en écrivant du code comme:
#ifndef _WIN32
Sleep(1000);
#endif
Une telle réponse ne devrait pas être votée positivement. Le but est d'être subtil. Idéalement, votre code devrait regarder comme ce n'est pas dépendant de la plate - forme du tout. Si vous n'avez des déclarations (ou des conditions basées sur ou ou autre), ils devraient avoir une justification plausible (basée sur un mensonge, bien sûr).#ifdef
os.name
System.Environment.OSVersion
Inclure dans votre réponse
- Le code
- Vos plateformes «favorites» et «défavorisées».
- Une entrée avec laquelle tester votre programme.
- Le temps d'exécution sur chaque plate-forme, pour la même entrée.
- Une description des raisons pour lesquelles le programme s'exécute si lentement sur la plate-forme défavorable.
Réponses:
C
CleverSort
CleverSort est un algorithme de tri de chaîne en deux étapes de pointe (c'est-à-dire sur-conçu et sous-optimal).
À l'étape 1, il commence par pré-trier les lignes d'entrée à l'aide du tri radix et les deux premiers octets de chaque ligne. Le tri Radix n'est pas comparatif et fonctionne très bien pour les chaînes.
À l'étape 2, il utilise le tri par insertion sur la liste de chaînes pré-triée. Comme la liste est presque triée après l'étape 1, le tri par insertion est assez efficace pour cette tâche.
Code
Plateformes
Nous savons tous que les machines big-endian sont beaucoup plus efficaces que leurs homologues little-endian. Pour l'analyse comparative, nous compilerons CleverSort avec les optimisations activées et créerons au hasard une énorme liste (un peu plus de 100 000 chaînes) de lignes de 4 octets:
Référence Big-endian
Pas trop mal.
Bechmark de Little-endian
Boo, petit Endian! Huer!
La description
Le tri par insertion est vraiment assez efficace pour les listes presque triées, mais il est horriblement inefficace pour les listes triées aléatoirement.
La partie sournoise de CleverSort est la macro FIRSTSHORT :
Sur les machines big-endian, ordonner une chaîne de deux entiers 8 bits lexicographiquement ou les convertir en entiers 16 bits et les ordonner ensuite donne les mêmes résultats.
Naturellement, cela est également possible sur les machines peu endiennes, mais la macro aurait dû être
qui fonctionne comme prévu sur toutes les plateformes.
Le "benchmark big-endian" ci-dessus est en fait le résultat de l'utilisation de la macro appropriée.
Avec la mauvaise macro et une petite machine endian, la liste est pré-triée par le deuxième caractère de chaque ligne, résultant en un ordre aléatoire du point de vue lexicographique. Le tri par insertion se comporte très mal dans ce cas.
la source
Python 2 contre Python 3
Évidemment, Python 3 est plus rapide de plusieurs ordres de grandeur que Python 2. Prenons l'exemple de cette implémentation de l' algorithme Shellsort :
Code
Référence
Préparez une entrée de test. Ceci est tiré de la réponse de Dennis mais avec moins de mots - Python 2 est tellement lent ...
Python 2
Python 3
Où est le code sournois?
Je suppose que certains lecteurs peuvent vouloir traquer le filou eux-mêmes, alors je cache la réponse avec une balise de spoiler.
Bonus 1:
Bonus 2:
la source
flag
semble en écriture seule, ne pouvez-vous pas le supprimer? En outre, celar
semble superflu si vous le faitesif lst[i+h] < lst[i]: ...
. D'un autre côté, si vous continuezr
pourquoi le swap? Ne pourriez-vous pas simplement fairelst[i+h] = lst[i]
? Tout cela est-il une distraction intentionnelle?