Ce défi est assez simple:
vous disposez d'un tableau d'entiers positifs (non compris 0) et devez sélectionner un élément aléatoire dans ce tableau.
Mais voici la torsion:
La probabilité de sélectionner un élément dépend de la valeur de l'entier, ce qui signifie que plus le nombre augmente, plus sa probabilité d'être sélectionné l'est aussi!
Exemple
On vous donne le tableau [4, 1, 5]
.
La probabilité de sélectionner 4 est égale à 4 divisée par la somme de tous les éléments du tableau , dans ce cas 4 / ( 4 + 1 + 5 ) = 4 / 10 =
40%
.
La probabilité de sélectionner 1 est 1 / 10
ou 10%
.
Contribution
Un tableau d'entiers positifs.
Production
Renvoyez l'entier sélectionné si vous utilisez une méthode, ou imprimez-le directement dans stdout
.
Règles
- C'est le code-golf donc le code le plus court en octets dans n'importe quelle langue gagne.
- Les failles standard sont interdites.
R , 25 octets
Essayez-le en ligne!
Explication:
Prend un échantillon
s
de taille1
sans remplacement, avec des poidss
; ceux-ci sont redimensionnés pour être des probabilités.Pour vérifier la distribution, utilisez ce lien .
la source
Pyth , 4 octets
Essayez-le ici.
Sauvegardé d'un octet, grâce à @Jakube, avec une approche assez inhabituelle.
Pyth , 5 octets
Essayez-le ici!
Comment?
#1
# 2
la source
OsmL
ouOsmR
d
, puis cartographied
sur une plage ... génie!CJam (9 octets)
Démo en ligne . Il s'agit d'un programme complet qui prend l'entrée au format tableau CJam sur stdin et imprime l'élément sélectionné sur stdout.
Dissection
la source
Perl 6 , 20 octets
1 octet enregistré grâce à @Brad Gilbert b2gills.
Essayez-le en ligne!
Cela prend 1 argument de liste. Nous compressons 2 copies de cette liste en utilisant l'
xx
opérateur. Donc, avec@_ Zxx@_
, nous obtenons une liste dans laquelle l'élémentx
est présentéx
fois. Il est ensuite contraintBag
, qui est une collection qui stocke des objets ainsi que le nombre de fois qu'ils apparaissent dans la collection. Enfin, nous choisissons un élément aléatoire de cette collection avecpick
, qui prend les comptes en compte et fait The Right Thing ™.la source
{bag(@_ Z=>@_).pick}
{bag(@_ Zxx@_).pick}
Python 3.6 , 44 octets
Oui pour les intégrés. L'autre
A
danschoices(A, A)
est unweights
argument facultatif .Essayez-le en ligne!
la source
MATL ,
86 octetsEssayez-le sur MATL Online!
Explication
la source
Mathematica, 19 octets
la source
Rubis , 32 octets
Essayez-le en ligne!
la source
Python 3 , 62 octets
Essayez-le en ligne!
la source
Java (OpenJDK 8) ,
88878683 octetsEssayez-le en ligne!
la source
for(r*=Math.random();;)
est nécessaire, ou si tout ce dont vous avez besoin estr*=Math.random()
.for(;;)
boucle, cela nécessiterait une seconde instruction de retour (jamais atteinte) après lefor(int i:a)...
pour satisfaire le compilateur - ce qui serait 3 octets de plus.for(int i:a)
êtes comme unforeach
C #. J'ai eu le même problème, mais j'ai juste utilisé unfor
qui boucle continuellement. Votre nouvelle réponse m'intrigue, je pourrais essayer de chaparder certaines de vos idées.J,
878 octetsLe 7 octet n'est pas valide; Je reviendrai sur une modification précédente lorsque je reviendrai sur mon ordinateur dans un jour ou deux.
Essayez-le en ligne!
:( la sélection d'éléments aléatoires dans un tableau est coûteuse.
8 octets
9 octets
Explication
la source
?@+/
est(?@+)/
; Je crains que vous n'ayez à repousser cela jusqu'à 8 à nouveau…JavaScript (ES6), 50 octets
Si tout va bien il est évident comment cela fonctionne, mais je l'expliquerai quand même ici. Il trie les entiers par ordre décroissant, puis en choisit un au hasard avec une distribution bêta (1 / 2,1) .
la source
a=[4,1,5]
, vous obtiendrez environ 18%1
, 24%4
et 58%5
, ce qui suggère que vous obtiendrez cette distribution avec n'importe quelle entrée de longueur 3.05AB1E , 9 octets
Essayez-le en ligne!
la source
PowerShell , 27 octets
Essayez-le en ligne!
Prend l'entrée
$args[0]
comme un tableau littéral. Boucle à travers chaque élément|%{...}
et chaque itération construit un nouveau tableau,$_
d'$_
éléments - par exemple, pour4
cela va créer un tableau@(4,4,4,4)
. Ces éléments du tableau sont ensuite canalisés dansGet-Random
lesquels arrachera l'un des éléments avec une probabilité (pseudo) égale. Puisque, par exemple,@(4,1,5)
cela nous donne@(4,4,4,4,1,5,5,5,5,5)
cela satisfait aux exigences de probabilité.la source
C # (.NET Core) ,
93898776 + 18 = 94 octetsEssayez-le en ligne!
18 octets supplémentaires pour
using System.Linq;
Remerciements
11 octets économisés grâce à Nevay, dont l'implémentation du nombre aléatoire était beaucoup plus concise (en plus d'être un
int
au lieu d'undouble
).Dégolfé
Explication
Obtenez un nombre aléatoire
r
, entre 0 et la somme des éléments. Ensuite, à chaque itération, soustrayez l'élément courantr
. Sir
est inférieur à0
, renvoyez cet élément. L'idée est qu'il existe de plus grandes parties du nombre aléatoire pour les plus grands nombres dans le tableau.la source
a=>{int i=-1,r=new Random().Next(a.Sum());for(;r>=0;)r-=a[++i];return a[i];}
Japt , 7 octets
Testez-le ici
Explication
Entrée implicite du tableau
U
.Mappez sur le tableau en passant chaque élément à travers une fonction où
D
est l'élément actuel.Générez un tableau de longueur
D
et remplissez-le avecD
.Aplatir.
Obtenez un élément aléatoire.
la source
CJam , 5 octets
Essayez-le en ligne! Remarque: nombres séparés par un espace
la source
Perl, 31 octets
Cela suppose que l'entrée est des arguments de ligne de commande. Notez qu'il peut manquer de mémoire si les nombres sont importants.
la source
Perl 5 , 31 + 1 (-a) = 32 octets
Essayez-le en ligne!
la source
GolfScript , 17 octets
Essayez-le en ligne!
la source
Fusain , 12 octets
Essayez-le en ligne! Le lien est vers la version détaillée du code. Étant donné que Charcoal essaie d'être trop intelligent, je dois utiliser une entrée délimitée par des points-virgules pour le tableau. Explication:
la source
Haskell , 87 octets
Essayez-le en ligne!
la source
Javascript (ES6),
6154 octets-7 octets grâce à @Justin Mariner
Exemple d'extrait de code
la source
eval(a.join`+`)
au lieu dereduce
.[].find(m=>(n-=m)<0,n=Math.random()*eval(a.join
+))
et appeler avecinput::[].find(...)
Haskell ,
7877 octetsEssayez-le en ligne! Exemple d'utilisation:
f [1,99]
donne probablement99
.Explication:
f
prend une liste d'entiersl
et retourne l'entier sélectionné au hasard commeIO Int
.l>>= \n->n<$[1..n]
construit une liste avec chaque élémentn
répété plusieursn
fois.randomRIO(0,sum l-1)
renvoie un entier compris entre 0 et la longueur de la liste des éléments répétés, qui est exactement la somme de tous les éléments, moins un pour éviter une exception hors limite.Bonus: version sans point de 85 octets
Essayez-le en ligne!
la source
Bash , 51 octets
Prend des entrées séparées par des espaces ou des sauts de ligne dans un ou plusieurs arguments.
Essayez-le en ligne!
Validez les fréquences aléatoires avec un cas de test plus compliqué.
la source
Java 8,
127122121 bytes-1 byte thanks to @Nevay.
Uses a similar approach as @ErikTheOutgolfer's Jelly answer, by adding
n
times the itemn
to the list, and then select one randomly from that list.Explanation:
Try it here.
la source
#shuffle
call into the for loop to save 1 bytefor(int j=i;j-->0;Collections.shuffle(l))l.add(i);
.Dyalog APL, 8 bytes
Try it online!
How?
/⍨
,n
copies ofn
for eachn
in the argument.⌷⍨
, at the index of1?
, a random value between1
and+/
, the sum of the argumentla source
GNU APL 1.2,
2623 bytes; 1.72119 bytesApproach inspired by Erik the Outgolfer's Jelly answer. Relies on
⎕IO
being 0 instead of 1, which is the default for GNU APL (sort of +5 bytes for⎕IO←0
).-3, -2 bytes thanks to @Zacharý
∇
function formAnonymous lambda form
For the explanation, I will use
⍵
to represent the argument passed to the function, but it is equivalent toR
in the∇
form.⍵∘.⍴⍵
computes the outer product on the list using the reshape (⍴
) operator. Effectively, this creates a table (like a multiplication table) but instead of multiplying, it repeats the element in the column a number of times equal to the element in the row. For the example given in the question, this is:0 0⍉⍵∘.⍴⍵
transposes the matrix and returns just the main diagonal. This gives us just the parts where the row and column in⍵∘.⍴⍵
were the same i.e. we repeated the number a number of times equal to its value. For the example, this is:∊
turns its argument into a list. Using the transpose (⍉
) operator, we got a vector containing 3 vectors. Enlist (∊
) turns it into a single vector containing all the elements.S←...
assigns this new vector to vectorS
.⍴S
gives us the length of that list.?
is the random operator, so?⍴S
gives us a random number between 0 and the length of the list (exclusive) (this is why it relies on⎕IO
being 0; otherwise it's between 1 and the length, inclusive).S[...]
returns the element at the given index.la source
Q
, since you never use it. And IIRC you can remove the newline before the del (little triangle-thing marking the end of the function.)<IO> <IO>⍉
to get the main diagonal was even a thing!MATLAB, 30 bytes
This assumes MATLAB R2015a or newer and with the Statistics & Machine Learning toolbox installed.
See the explanation below for how
repelem
is used. The difference between this shorter one and the one below is that the S&ML toolbox includes the functiondatasample
which can be used to take one or more elements from an array at random (with uniform probability) which allows an anonymous function to be used, stripping away theinput/disp
calls.MATLAB, 49 bytes
This code assumes that MATLAB R2015a or newer is used as that is when the
repelem
function was introduced.repelem
is a function which takes two parameters, the first is an array of numbers to be replicated, and the second is an array of how many times the corresponding element should be replicated. Essentially the function performs run-length decoding by providing the number and the run-length.By providing the same input to both inputs of
repelem
we end up with an array which consists of n times more of element n if that makes sense. If you provided[1 2 3]
you would get[1 2 2 3 3 3]
. If you provided[1 2 4 2]
you would get[1 2 2 4 4 4 4 2 2]
. By doing this it means that if we select an element with uniform probability (randi(m)
gives a random integer from 1 to m with uniform probability), each element n has an n times higher probability of being selected. In the first example of[1 2 3]
,1
would have a 1/6 chance,2
would have a 2/6 chance and3
would have a 3/6 chance.As a side note, because
repelem
is not available yet for Octave, I can't give a TIO link. Additionally because Octave can't be used there is a big character penalty asinput()
anddisp()
need to be used as an anonymous function is not possible. If Octave supportedrepelem
, the following could be used:That would have saved 16 bytes, but it was not to be.
la source