Créez une fonction qui produira un ensemble de nombres aléatoires distincts tirés d'une plage. L'ordre des éléments de l'ensemble est sans importance (ils peuvent même être triés), mais il doit être possible que le contenu de l'ensemble soit différent à chaque appel de la fonction.
La fonction recevra 3 paramètres dans l'ordre que vous souhaitez:
- Nombre de nombres dans le jeu de sortie
- Limite inférieure (incluse)
- Limite supérieure (incluse)
Supposons que tous les nombres sont des entiers compris entre 0 (inclus) et 2 31 (exclusif). La sortie peut être renvoyée comme vous le souhaitez (écriture sur la console, sous forme de tableau, etc.)
Juger
Les critères incluent les 3 R
- Exécution - testé sur une machine quadricœur Windows 7 avec le compilateur disponible librement ou facilement (fournissez un lien si nécessaire)
- Robustesse - la fonction gère-t-elle les cas d'angle ou va-t-elle tomber dans une boucle infinie ou produire des résultats invalides - une exception ou une erreur sur une entrée invalide est valide
- Randomness - il devrait produire des résultats aléatoires qui ne sont pas facilement prévisibles avec une distribution aléatoire. L'utilisation du générateur de nombres aléatoires intégré est très bien. Mais il ne devrait pas y avoir de biais évidents ni de schémas prévisibles évidents. Doit être meilleur que ce générateur de nombres aléatoires utilisé par le service de comptabilité de Dilbert
S'il est robuste et aléatoire, il se résume à l'exécution. Ne pas être robuste ou aléatoire nuit grandement à son classement.
code-challenge
fastest-code
number
random
Jim McKeeth
la source
la source
Réponses:
Python
J'ai probablement juste réinventé un algorithme bien connu, mais l'idée est d'effectuer (conceptuellement) un shuffle partiel de Fisher-Yates de la plage
lower..upper
pour obtenir len
préfixe de longueur d'une plage uniformément mélangée.Bien sûr, le stockage de toute la gamme serait plutôt coûteux, donc je ne stocke que les emplacements où les éléments ont été échangés.
De cette façon, l'algorithme devrait bien fonctionner à la fois dans le cas où vous échantillonnez des nombres à partir d'une plage étroite (par exemple 1000 nombres dans la plage 1 à 1000), ainsi que dans le cas où vous échantillonnez des nombres à partir d'une large plage .
Je ne suis pas sûr de la qualité du caractère aléatoire du générateur intégré en Python, mais il est relativement simple d'échanger n'importe quel générateur qui peut générer uniformément des entiers à partir d'une certaine plage.
la source
python 2.7
Je ne sais pas quel est votre statut en utilisant des méthodes aléatoires intégrées, mais vous y allez quand même. agréable et court
edit: vient de remarquer que range () n'aime pas faire de grandes listes. entraîne une erreur de mémoire. verra s'il y a une autre façon de le faire ...
edit2: la plage n'était pas la bonne fonction, xrange fonctionne. L'entier maximum est en fait
2**31-1
pour pythontester:
la source
C
Renvoie un tableau contenant x entrées aléatoires uniques entre min et max. (l'appelant doit libérer)
Fonctionne en générant x entiers aléatoires séquentiels dans la plage, puis en les mélangeant. Ajoutez un
seed(time)
endroit dans l'appelant si vous ne voulez pas les mêmes résultats à chaque exécution.la source
Rubis> = 1.8.7
la source
R
la source
La question n'est pas correcte. Avez-vous besoin d'un échantillonnage uniforme ou non? Dans le cas où un échantillonnage uniforme est nécessaire, j'ai le code suivant dans R, qui a une complexité moyenne O ( s log s ), où s est la taille de l'échantillon.
Bien sûr, on peut le réécrire en C pour de meilleures performances. La complexité de cet algorithme est discutée dans: Rouzankin, PS; Voytishek, AV Sur le coût des algorithmes de sélection aléatoire. Méthodes de Monte Carlo Appl. 5 (1999), no. 1, 39-54. http://dx.doi.org/10.1515/mcma.1999.5.1.39
Vous pouvez chercher dans cet article un autre algorithme avec la même complexité moyenne.
Mais si vous n'avez pas besoin d'un échantillonnage uniforme, exigeant seulement que tous les nombres échantillonnés soient différents, la situation change radicalement. Il n'est pas difficile d'écrire un algorithme qui a une complexité moyenne O ( s ).
Voir aussi pour un échantillonnage uniforme: P. Gupta, GP Bhattacharjee. (1984) Un algorithme efficace pour l'échantillonnage aléatoire sans remplacement. Journal international de mathématiques informatiques 16: 4, pages 201-209. DOI: 10.1080 / 00207168408803438
Teuhola, J. et Nevalainen, O. 1982. Deux algorithmes efficaces pour l'échantillonnage aléatoire sans remplacement. / IJCM /, 11 (2): 127–140. DOI: 10.1080 / 00207168208803304
Dans le dernier article, les auteurs utilisent des tables de hachage et affirment que leurs algorithmes ont une complexité O ( s ). Il existe un autre algorithme de table de hachage rapide, qui sera bientôt implémenté dans pqR (assez rapide R): https://stat.ethz.ch/pipermail/r-devel/2017-October/075012.html
la source
APL,
1822 octetsDéclare une fonction anonyme qui prend deux arguments
⍺
et⍵
.⍺
est le nombre de nombres aléatoires que vous souhaitez,⍵
est un vecteur contenant les bornes inférieure et supérieure, dans cet ordre.a?b
choisita
des nombres aléatoires entre 0 etb
sans remplacement. En prenant,⍵[1]-⍵[0]
nous obtenons la taille de la plage. Ensuite, nous choisissons des⍺
nombres (voir ci-dessous) dans cette plage et ajoutons la borne inférieure. En C, ce serait⍺
fois sans remplacement. Les parenthèses ne sont pas nécessaires car APL fonctionne de droite à gauche.En supposant que j'ai bien compris les conditions, cela échoue aux critères de «robustesse» car la fonction échouera si on lui donne des arguments incorrects (par exemple en passant un vecteur au lieu d'un scalaire⍺
).Dans le cas où il
⍺
s'agit d'un vecteur plutôt que d'un scalaire,1↑⍺
prend le premier élément de⍺
. Pour un scalaire, c'est le scalaire lui-même. Pour un vecteur, c'est le premier élément. Cela devrait faire en sorte que la fonction réponde aux critères de «robustesse».Exemple:
la source
{⍵+⍺?⎕-⍵}
devrait donc suffire, où l'invite est pour la limite supérieure et l'argument de droite est la limite inférieureScala
compiler et exécuter:
La deuxième ligne exécutera 200 tests avec 15 valeurs de 0 à 100, car Scala produit un bytecode rapide mais nécessite un certain temps de démarrage. Ainsi, 200 départs avec 15 valeurs de 0 à 100 prendraient plus de temps.
Exemple sur un monocœur 2 Ghz:
Logique:
Utiliser les nombres aléatoires et de manière récursive intégrés dans la plage (max-min), ajouter min et vérifier si la taille de l'ensemble est la taille attendue.
La critique:
la source
Schème
Je ne sais pas pourquoi vous avez besoin de 3 paramètres passés ni pourquoi je dois assumer une plage ...
la source
R
la source
C ++
Ce code est préférable lors du prélèvement de nombreux échantillons de la plage.
la source
max-min
est beaucoup plus grand quen
. En outre, la séquence de sortie augmente de façon monotone, vous obtenez donc un caractère aléatoire de très faible qualité tout en payant le coût d'appelerrand()
plusieurs fois par résultat. Un shuffle aléatoire du tableau vaudrait probablement la peine d'être exécuté plus longtemps.Q (19 caractères)
Utilisez ensuite f [x; y; z] comme [nombre de nombres dans l'ensemble de sortie; point de départ; taille de la plage]
Par exemple, f [5; 10; 10] produira 5 nombres aléatoires distincts entre 10 et 19 inclus.
Les résultats ci-dessus montrent des performances à 100 000 itérations de sélection de 100 nombres aléatoires entre 1 et 10 000.
la source
R, 31 ou 40 octets (selon la signification du mot «plage»)
Si l'entrée a 3 nombres,
a[1], a[2], a[3]
et par "plage" vous voulez dire "une séquence entière d'un [2] à un [3]", alors vous avez ceci:Si vous avez un tableau à
n
partir duquel vous êtes sur le point de rééchantillonner, mais sous la restriction des limites inférieure et supérieure, comme «rééchantillonner les valeurs du tableau donné àn
partir de la plagea[1]...a[2]
», alors utilisez ceci:Je suis assez surpris de constater que le résultat précédent n'a pas été joué au vu de l'échantillon intégré avec des installations de remplacement! Nous créons un vecteur qui satisfait la condition de plage et le ré-échantillonnons.
la source
0:(2^31)
provoque unError: cannot allocate a vector of size 16.0 Gb
Javascript (en utilisant une bibliothèque externe) (64 octets / 104 octets ??)
Lien vers la bibliothèque: https://github.com/mvegh1/Enumerable/
Explication du code: l'expression Lambda accepte min, max, compte comme arguments. Créez une collection de taille n et mappez chaque élément à un nombre aléatoire correspondant aux critères min / max. Convertissez en tableau JS natif et renvoyez-le. J'ai également exécuté cela sur une entrée de taille 5 000 000, et après avoir appliqué une transformation distincte, j'ai toujours montré 5 000 000 d'éléments. S'il est convenu que ce n'est pas suffisamment sûr pour garantir la distinction, je mettrai à jour la réponse
J'ai inclus quelques statistiques dans l'image ci-dessous ...
EDIT: L'image ci-dessous montre le code / les performances qui garantissent que chaque élément sera distinct. C'est beaucoup plus lent (6,65 secondes pour 50000 éléments) que le code d'origine ci-dessus pour les mêmes arguments (0,012 secondes)
la source
K (oK) , 14 octets
Solution:
Essayez-le en ligne!
Exemple:
Explication:
Prend 3 entrées implicites par spécification:
x
, nombre de nombres dans l'ensemble de sortie,y
, limite inférieure (inclus)z
, limite supérieure (inclus)Remarques:
Également un polyglotte
q/kdb+
avec un jeu supplémentaire de crochets:{y+((-)x)?1+z-y}
(16 octets).la source
Axiom + sa bibliothèque
La fonction f () ci-dessus renvoie comme erreur la liste vide, dans le cas f (n, a, b) avec a> b. Dans d'autres cas d'entrée non valide, il ne s'exécute pas avec un seul message d'erreur dans la fenêtre Axiom, car l'argument ne sera pas du bon type. Exemples
la source