Voici un modèle assez courant pour les algorithmes de tri:
def sort(l):
while not is_sorted(l):
choose indices i, j
assert i < j
if l[i] > l[j]:
l[i], l[j] = l[j], l[i]
Ces algorithmes fonctionnent bien car les indices i
et j
sont choisis avec soin, en fonction de l'état de la liste l
.
Cependant, que se passerait-il si nous ne pouvions pas voir l
et si nous devions simplement choisir aveuglément? À quelle vitesse pourrions-nous alors trier la liste?
Votre défi consiste à écrire une fonction qui génère une paire aléatoire d'indices, étant donné uniquement la longueur de l
. Plus précisément, vous devez générer deux index,, i, j
avec 0 <= i < j < len(l)
. Votre fonction devrait fonctionner sur n'importe quelle longueur de liste, mais elle sera notée sur une liste de longueur 100.
Votre score est le nombre moyen de choix d'index nécessaires pour trier une liste uniformément aléatoire au hasard selon le modèle ci-dessus, où les indices sont choisis en fonction de votre fonction.
Je noterai les soumissions, en prenant le nombre moyen de choix d'index sur 1000 essais sur une liste uniformément aléatoire de 100 de longueur sans entrées répétées.
Je me réserve le droit d'exécuter moins d'essais si la soumission est clairement non compétitive ou ne se termine pas, et j'exécuterai plus d'essais pour différencier les meilleurs concurrents afin de trouver un seul gagnant. Si plusieurs soumissions principales restent dans la marge d'erreur à la limite de mes ressources de calcul, je déclarerai la soumission antérieure gagnante, jusqu'à ce que d'autres ressources de calcul puissent être utilisées.
Voici un exemple de programme de notation, en Python:
import random
def is_sorted(l):
for x in range(len(l)-1):
if l[x] > l[x+1]:
return False
return True
def score(length, index_chooser):
steps = 0
l = list(range(length))
random.shuffle(l)
while not is_sorted(l):
i, j = index_chooser(length)
assert (i < j)
if l[i] > l[j]:
l[i], l[j] = l[j], l[i]
steps += 1
return steps
Votre fonction ne peut pas conserver tout état mutable, interagissent avec les variables globales, affectent la liste l
, etc. entrée uniquement de votre fonction doit être la longueur de la liste l
, et il doit sortir une paire ordonnée d'entiers dans la plage [0, len(l)-1]
(ou approprié pour votre de la langue indexation des listes). N'hésitez pas à demander si quelque chose est autorisé dans les commentaires.
Les soumissions peuvent être dans n'importe quelle langue gratuite. Veuillez inclure un harnais de notation si celui-ci n'a pas encore été publié pour votre langue. Vous pouvez poster un score provisoire, mais je laisserai un commentaire avec le score officiel.
La notation est le nombre moyen d'étapes vers une liste triée sur une liste uniformément aléatoire de longueur 100. Bonne chance.
la source
Réponses:
Python, score = 4508
Confirmation de Half-Life 3.
Python, score = 11009
Apparemment, un tri à bulles aléatoire ne fait pas bien pire qu'un tri à bulles normal.
Distributions optimales pour petite longueur
Il n'y a aucun moyen que cela puisse être étendu à 100, mais c'est intéressant à regarder de toute façon. J'ai calculé les distributions optimales pour les petits cas (longueur ≤ 7) en utilisant la descente de gradient et beaucoup d'algèbre matricielle. La k ème colonne montre la probabilité de chaque swap à la distance k .
la source
h
c'est la distance entre les éléments échangés; il ne représente ni l'avant ni l'arrière.Résultat: 4627
Essayez-le en ligne!
Génère des indices aléatoires dont la distance est choisie uniformément
[1,1,4,16]
. L'idée est d'avoir un mélange de swaps en une étape avec des swaps à plus grande échelle.J'ai modifié à la main ces valeurs pour des listes de longueur 100, et elles sont probablement loin d'être optimales. Une recherche automatique pourrait probablement optimiser la distribution sur les distances pour la stratégie de paire aléatoire avec la distance choisie.
la source
Résultat: 28493
Essayez-le en ligne!
Cette solution sélectionne simplement des valeurs distinctes pour
x
et dey
manière aléatoire dans la plage et les renvoie dans l'ordre trié. Pour autant que je sache, cela fonctionne mieux que de choisirx
puis de choisiry
parmi les valeurs restantes.la source
Python, score: 39525
Essayez-le en ligne.
la source
Python, score ≈ 5000
Essayé avec un tas de valeurs epsilon, 0,25 semble être le meilleur.
Score ≈ 8881
Une approche différente. Pas aussi bon, et il meurt horriblement avec une longueur non divisible par le nombre de segments, mais toujours amusante à construire.
la source
Résultat: 4583
Essayez-le en ligne!
Je ne sais pas pourquoi. Je viens d'essayer des séquences répertoriées sur wikipedia artical pour shellsort . Et celui-ci semble fonctionner le mieux. Il obtient un score similaire avec celui xnor publié .
la source
candidates
de la fonction en tant que variable globale devrait fonctionner.Python 2 , 4871
Essayez-le en ligne!
la source