À propos de la série
Tout d'abord, vous pouvez traiter cela comme n'importe quel autre défi de golf de code et y répondre sans vous soucier de la série. Cependant, il existe un classement pour tous les défis. Vous pouvez trouver le classement avec plus d'informations sur la série dans le premier post .
Bien que j'ai un tas d'idées alignées pour la série, les défis futurs ne sont pas encore gravés dans le marbre. Si vous avez des suggestions, faites-le moi savoir sur la publication sandbox correspondante .
Trou 2: nombres d'une distribution normale
Je ne peux pas croire que cela n'ait pas encore été fait! Vous devez générer des nombres aléatoires, à partir d'une distribution normale . Certaines règles (la plupart d'entre elles sont probablement couvertes automatiquement par la plupart des soumissions, mais certaines sont en place pour garantir la cohérence des résultats entre des langues très différentes):
Vous devez prendre deux entiers non négatifs en entrée : une valeur de départ
S
et le nombreN
de nombres à renvoyer. La sortie doit être une liste deN
nombres à virgule flottante, tirée d'une distribution normale avec une moyenne de 0 et une variance de 1 . Chaque fois que votre soumission reçoit la même graine,S
elle doit produire le même nombre. En particulier, si elle est appelée une fois avec et une fois avec , les premières entrées des deux sorties doivent être identiques. De plus, au moins 2 16 valeurs différentes de devraient produire des séquences différentes.(S, N1)
(S, N2)
min(N1, N2)
S
Vous pouvez utiliser n'importe quel générateur de nombres aléatoires intégré documenté pour tirer des nombres d'une distribution (approximativement) uniforme , à condition que vous puissiez le transmettre
S
et qu'il prenne en charge au moins 2 16 graines différentes. Si vous le faites, le RNG devrait être en mesure de renvoyer au moins 2 20 valeurs différentes pour tout nombre donné que vous lui demandez.- Si votre RNG uniforme disponible a une gamme plus petite, n'est pas semable ou prend en charge trop peu de graines, vous devez d'abord construire un RNG uniforme avec une gamme suffisamment large au-dessus de celui intégré ou vous devez implémenter votre propre RNG approprié en utilisant la graine. Cette page peut être utile pour cela.
- Si vous n'implémentez pas d'algorithme établi pour générer des distributions normales, veuillez inclure une preuve d'exactitude. Dans les deux cas, l'algorithme que vous choisissez doit produire une distribution normale théoriquement exacte (sauf limitations des PRNG sous-jacents ou types de données à précision limitée).
- Votre implémentation doit utiliser et renvoyer des nombres à virgule flottante (au moins 32 bits de large) ou des nombres à virgule fixe (au moins 24 bits de large) et toutes les opérations arithmétiques doivent utiliser la pleine largeur du type choisi.
- Vous ne devez pas utiliser de fonctions intégrées directement liées à la distribution normale ou aux intégrales gaussiennes, comme la fonction d'erreur ou son inverse.
Vous pouvez écrire un programme complet ou une fonction et prendre une entrée via STDIN, un argument de ligne de commande, un argument de fonction ou une invite et produire une sortie via une valeur de retour ou en imprimant vers STDOUT (ou l'alternative la plus proche).
S
et N
seront des entiers non négatifs, chacun inférieur à 2 20 . La sortie peut être dans n'importe quelle liste ou format de chaîne pratique et sans ambiguïté.
Il s'agit du code golf, donc la soumission la plus courte (en octets) l'emporte. Et bien sûr, la soumission la plus courte par utilisateur entrera également dans le classement général de la série.
Classement
Le premier post de la série génère un classement.
Pour vous assurer que vos réponses s'affichent, veuillez commencer chaque réponse par un titre, en utilisant le modèle Markdown suivant:
# Language Name, N bytes
où N
est la taille de votre soumission. Si vous améliorez votre score, vous pouvez conserver les anciens scores dans le titre, en les barrant. Par exemple:
# Ruby, <s>104</s> <s>101</s> 96 bytes
(La langue n'est pas actuellement affichée, mais l'extrait de code l'exige et l'analyse, et je pourrai ajouter un classement par langue à l'avenir.)
Réponses:
Dyalog APL, 33 octets
{(.5*⍨¯2×⍟?0)×1○○2×?0}¨⍳⎕⊣⎕rl←1+⎕
Box-Muller :
la source
⎕rl
pour êtreS+1
parce qu'il⎕rl←0
a une signification particulière.+1
, tout ce qu'elle dit, c'est que vous devez prendre en charge au moins 2 ^ 16 valeurs différentes. Donc, travailler correctement dans la plage [1..2 ^ 16] devrait être OK.R, 68 octets
Cela utilise la
runif()
fonction, qui génère des écarts aléatoires à partir d'une distribution uniforme. Le germe pour la génération de nombres aléatoires est spécifié à l'aide deset.seed()
, qui utilise par défaut l'algorithme de Mersenne-Twister avec une période de 2 ^ 19937-1.Le résultat est un vecteur R de longueur N contenant les écarts normaux standard calculés.
Il utilise la méthode de Box-Muller: pour deux variables aléatoires uniformes indépendantes U et V,
la source
f=
(la fonction n'a pas nécessairement besoin d'être nommée, si les fonctions sans nom sont quelque chose dans votre langage).Error: unexpected '}' in "f=fu...
, êtes-vous sûr d'obtenir les mêmes premiers numéros si vous appelezf(0,1)
etf(0,2)
?Dyalog APL,
4234C'est une fonction qui prend
S
comme argument de gauche etN
comme argument de droite.Il s'agit d'une implémentation de la transformation Box-Muller, utilisant l'opérateur aléatoire intégré de Dyalog APL
?
, qui par défaut est un twister Mersenne qui renvoie des valeurs 64 bits, ce qui devrait être suffisant.Explication:
⎕RL←⍺
: définissez la graine aléatoire sur⍺
.?⍵2⍴0
: générer des⍵
paires de nombres aléatoires entre 0 et 1.{
...}/
: appliquez la fonction suivante à chaque paire:(.5*⍨¯2×⍟⍺)×1○⍵×○2
: calcule laZ0
valeur (sqrt(-2 ln ⍺)×cos(2π⍵)
).la source
?0
renvoie un nombre à virgule flottante compris entre 0 et 1.Perl, 67
Box-Muller comme dans les autres entrées.
f
prend les paramètres dans l'ordreS, N
.Utilisation:
la source
Java,
164161 octetsCela prend l'entrée via la fonction et la sortie via la sortie standard. Il utilise la méthode Box-Muller.
la source
s=0;s++<n;
->;n-->0;
?Commodore 64 Basic,
767063 octetsÉtant donné que le jeu de caractères PETSCII contient certains symboles non présents dans Unicode, j'ai effectué des substitutions:
/
=SHIFT+N
,┌
=SHIFT+O
,●
=SHIFT+Q
,╮
=SHIFT+I
,─
=SHIFT+E
Cela implémente la transformation Box-Muller standard pour générer les nombres; J'ai choisi la moitié sin (x) de la transformation parce que Commodore 64 Basic a un raccourci à deux caractères pour
sin()
, mais pas pourcos()
.Bien que le manuel indique autrement, la valeur de l'argument à
RND
ne importe: si un nombre négatif est passé, le générateur de nombres aléatoires est non seulement réensemencées, il est réensemencées avec ce numéro . Cela rend l'ensemencement beaucoup plus simple: au lieu d'avoir besoin dePOKE
cinq emplacements de mémoire, je dois simplement faire un appel à ne rien faireRND
, ce qui réduit le code de deux lignes / 121 octets à 1 ligne / 76 octets.Edit: Golfed six bytes off en réalisant que je pouvais combiner les deux
INPUT
déclarations, et que l'espace aprèsTO
était facultatif.Edit: Golfed sept autres off: Commodore Basic a, en fait, Pi comme constante intégrée, et il est même saisissable sur un clavier moderne (
SHIFT+PgDn
, au cas où vous vous poseriez la question).la source
80386 code machine, 72 octets
Hexdump du code:
Voici le code source (peut être compilé par Visual Studio):
Ici, j'utilise un générateur de nombres aléatoires Lehmer . Il utilise l'algorithme suivant:
Ici, 4294967291 est un grand nombre (2 ^ 32-5) et 116 est un petit nombre (moins de 128; voir ci-dessous) qui est sa racine primitive . J'ai choisi une racine primitive qui a une distribution plus ou moins aléatoire de zéros et de uns en représentation binaire (01110100). Ce RNG a la période maximale possible de 4294967290, si la semence n'est pas nulle.
Les nombres relativement petits que j'ai utilisés ici (116 et 4294967291, qui peuvent également être représentés par -5) me permettent de profiter du
lea
codage des instructions:Il est assemblé à 3 octets si les nombres peuvent tenir dans 1 octet.
La multiplication et la division utilisent
edx
eteax
comme registres de travail, c'est pourquoi j'ai faitseed
le deuxième paramètre à la fonction (lafastcall
convention d'appel utiliseedx
pour passer le deuxième paramètre). De plus, le premier paramètre est passéecx
, ce qui est un bon endroit pour tenir un compteur: une boucle peut être organisée en 1 instruction!Pour convertir un entier en nombre à virgule flottante, j'ai exploité la représentation des nombres à virgule flottante simple précision: si je mets les 9 bits de haut (exposant) sur le motif de bits
001111111
et que je laisse les 23 bits de bas au hasard, je vais obtenir un nombre aléatoire compris entre 1 et 2. J'ai pris l'idée d' ici . Pour définir les 9 bits les plus élevés, j'ai utilisé du bidouillage surebx
:Pour générer deux nombres aléatoires, j'ai utilisé une boucle imbriquée de 2 itérations. Je l'ai organisé avec
xor
:Le code à virgule flottante implémente la transformation Box-Muller .
la source
Haskell, 118
144Exemple d'utilisation:
Le type de retour de
random
est contraint àFloat
, ce qui faitrandom
générer un flottant uniforme dans [0, 1). À partir de là, c'est une formule simlpe box-muller avec une magie inutile pour la génération de listes.la source
Golflua, 63
70Infos et instructions Golflua.
Renvoie une table contenant les valeurs. Dans l'exemple que j'utilise
~T.u( )
, qui est le même quereturn table.unpack( )
dans lua.De nombreux caractères ont été enregistrés en définissant l'environnement de la fonction sur
M
(akamath
).la source
SAS, 108
J'ai déjà posté une réponse en R plus courte que celle-ci, mais il y a très peu de réponses SAS sur PPCG, alors pourquoi ne pas en ajouter une autre?
Avec un espace blanc:
Ceci définit une macro qui peut être appelée comme
%f(5, 3)
. La macro exécute une étape de données qui parcourt les entiers 1 à N, et à chaque itération, elle calcule un écart normal aléatoire à l'aide de Box-Muller et l'imprime dans le journal à l'aide de l'put
instruction.SAS n'a pas intégré pour pi, donc le mieux que nous puissions faire est de l'approximer avec arctangent.
La
ranuni()
fonction (qui est obsolète mais nécessite quelques caractères de moins que la fonction plus récente) renvoie un nombre aléatoire à partir d'une distribution uniforme. La documentation SAS ne donne pas beaucoup de détails sur l'implémentation RNG, sauf qu'elle a une période de 2 ^ 31-2.Dans les macros SAS, les variables de macro sont référencées avec un précédent
&
et résolvent leurs valeurs au moment de l'exécution.Comme vous l'avez probablement vu, SAS est rarement un concurrent réel dans un concours de golf de code .
la source
Java, 193 octets
Bien que cela ne bat pas le leader Java actuel, j'ai décidé de publier quand même pour montrer une méthode de calcul différente. C'est une version golfée d'OpenJDK
nextGaussian()
.Avec des sauts de ligne:
la source
(s,n)->{java.util.Random r=new java.util.Random(s);for(float a,v;n-->0;System.out.println(v*Math.sqrt(-2*Math.log(a)/a)))for(a=0;a>=1|a==0;a=v*v+(v=2*r.nextFloat()-1)*v)v=2*r.nextFloat()-1;}
T-SQL, 155 octets
À utiliser avec EXEC RS, N car il n'y a pas STD_IN dans T-SQL où S et N sont respectivement la graine et N. S produira des séquences "aléatoires" (RAND (graine) est une très mauvaise implémentation de nombres aléatoires) lorsque S> 2 ^ 16 (probablement avant cela, mais je ne le garantis pas). Utilise Box-Muller comme la plupart des solutions jusqu'à présent. 8388607 est 2 ^ 23-1, ce qui devrait, espérons-le, générer 2 ^ 20 valeurs différentes.
la source
Powershell, 164 octets
Identique à la plupart des réponses avec Box-Muller. Pas très expérimenté avec Powershell, donc toute aide au golf serait appréciée.
la source
Rubis, 72 octets
Entrée (en tant que fonction lambda):
Production:
PS: Je voudrais savoir si cela peut être approfondi. Je suis juste un débutant.
la source
Matlab, 77
La première entrée doit être
n
, la secondes
.la source
Octave,
919688 octetsOu, avec des espaces:
Réglez la graine à l'avant et utilisez la méthode Box-Mueller.
NB: Octave permet de générer des tableaux de nombres aléatoires et peut utiliser des opérations standard sur ces tableaux qui produisent des sorties de tableau. L'
.*
opérateur est la multiplication élément par élément de deux tableaux pour produire le résultat.la source
n(0,1)
et quen(0,2)
vous obtenez des premiers numéros différents, n'est-ce pas ?Pyth, 32 octets
Aucun Python n'est actuellement utilisé dans les super-guillemets en raison des nouvelles fonctions de Pyth. Encore un autre Box-Mueller.
Cet espace au début est important.
L'ensemencement ne semble pas fonctionner dans l'interpréteur en ligne, mais il fonctionne très bien dans la version locale.L'interprète en ligne semble être corrigé, voici donc un permalien: permalienla source
.nZ
) qui n'était pas implémentée lorsque la question a été posée. (Elle a en fait été mise en œuvre aujourd'hui.) Par conséquent, cette réponse ne devrait pas faire partie du concours ( meta.codegolf.stackexchange.com/questions/4867/… ).STATA, 85 octets
Prend l'entrée via la norme dans (le premier nombre est S, puis N). Définit la valeur de départ à S. Définit le nombre d'observations à N. Fait une variable et définit sa valeur à la valeur de transformation de Box Muller (merci à @Alex de l'avoir montré). Répertorie ensuite toutes les observations dans un tableau avec l'en-tête de colonne a et les numéros d'observation à côté d'eux. Si cela ne vous convient pas, faites-le moi savoir et je pourrai supprimer les en-têtes et / ou les numéros d'observation.
la source
R, 89 octets
Je sais que R a déjà été fait, mais je voulais montrer une approche différente de la Box-Muller que tout le monde utilisait. Ma solution utilise le théorème de limite centrale .
la source
a
dans votre code n'est pas claire, de sorte que le résultat est "juste".)TI-Basic, 74 octets
C'est en
¹
fait l'opérateur inverse.la source
Perl,
150108107 octetsCela utilise la méthode polaire Marsaglia . Appelé avec f (S, N).
Déplacement de l'affectation de
$a
dans le calcul de$c
.107:
Suppression du stockage des numéros de rechange et de la définition de
$b
.108:
150:
la source
Swift,
144142Rien d'intelligent, juste de voir comment Swift fonctionne.
J'espérais pouvoir utiliser (0 ... n) .map {} mais le compilateur ne semble pas reconnaître la carte {} à moins que vous n'utilisiez un paramètre.
la source
forEach
si vous ne voulez pas de valeur de retour, et je suis à peu près sûr que_ in
c'est obligatoire/0xffffffff
sert btwHaskell , 97 octets
Essayez-le en ligne!
Juste votre transformation Box-Muller de base, sur une liste infinie de nombres aléatoires.
la source
Python 3 , 118 octets
Essayez-le en ligne!
la source
SmileBASIC, 81 octets
Eh bien, maintenant que j'ai répondu à la première question, je dois faire tout le reste ...
Générer des nombres aléatoires est pas cher, mais l' ensemencement de la RNG utilise la plus longue fonction builtin dans la langue,
RANDOMIZE
.Peut-être existe-t-il un moyen d'optimiser la formule. Je ne vois pas comment il est nécessaire d'utiliser deux appels RNG.
la source