Ma section locale d'ACM remet des prix de présence aux personnes qui viennent aux réunions. Vous obtenez une chance accrue de gagner si vous résolvez le puzzle de programmation, cependant (mais je résous toujours ce puzzle). Ainsi, certaines personnes ont 1 entrée, tandis que d'autres en ont 2. Mais attendez! Le fonctionnement du programme de tombola n'est pas en ajoutant une autre entrée lorsque quelqu'un résout le puzzle. Au lieu de cela, il garde une trace du nombre de "vies" d'une personne, décrémentant que si cette personne est choisie à chaque passage de son algorithme d'échantillonnage aléatoire. Donc ça marche comme ça:
Doorknob: 1. xnor: 2. Justin: 2. Alex: 1. Dennis: 2.
Ensuite, le programme choisit au hasard l'un des [Doorknob, xnor, Justin, Alex, Dennis]
, décrémente le nombre (disons qu'il choisit Justin
):
Doorknob: 1. xnor: 2. Justin: 1. Alex: 1. Dennis: 2.
Et répète. Si le nombre de "vies" de quelqu'un va à 0
(choisissons à Justin
nouveau), il est supprimé de la liste:
Doorknob: 1. xnor: 2. Alex: 1. Dennis: 2.
Cela continue jusqu'à ce qu'il reste une personne; cette personne est la gagnante.
Maintenant, la vraie question est, quelle était la probabilité que j'aurais gagné?
Vous recevrez deux entrées:
n
. C'est le nombre de personnes engagées dans le challengek
. Il s'agit du nombre de personnes (parmi celles-cin
) qui ont 2 vies. Ce numéro vous inclut toujours.
Donc, si j'avais une fonction p
et que j'appelais p(10, 5)
, ce serait la probabilité de gagner le prix où il y a 10 personnes au total, dont 5 n'ont qu'une vie, tandis que 5 (vous y compris) ont 2 vies.
Vous devez afficher la probabilité de gagner soit exactement, soit sous forme décimale. En tout cas, les réponses doivent être à juste et y compris la 4 ème décimale après la virgule décimale. Que vous arrondissiez ou non à ce chiffre dépend de vous.
Votre solution peut être une solution aléatoire qui génère la réponse à la 4 e décimale avec une probabilité élevée . Vous pouvez supposer que le RNG intégré que vous utilisez est vraiment aléatoire et qu'il doit produire la bonne réponse avec une probabilité d'au moins 90%.
De plus, votre code n'a besoin que de fonctionner n, k <= 1000
, même si j'ai fourni des cas de test plus grands que ceux pour les curieux.
Cas de test
Remarque: certaines d'entre elles sont des formules générales.
n, k | output
----------+---------
1, 1 | 1
2, 2 | 0.5
2, 1 | 0.75
3, 1 | 11/18 = 0.611111111
1000, 1 | 0.007485470860550352
4, 3 | 0.3052662037037037
k, k | 1/k
n, 1 | (EulerGamma + PolyGamma[1 + n])/n (* Mathematica code *)
| (γ + ψ(1 + n))/n
10, 6 | 0.14424629234373537
300, 100 | 0.007871966408910648
500, 200 | 0.004218184180294532
1000, 500 | 0.0018008560286627948
---------------------------------- Extra (not needed to be a valid answer)
5000, 601 | 0.0009518052922680399
5000, 901 | 0.0007632938197806958
Pour quelques autres vérifications, procédez p(n, 1) * n
comme suit:
n | output
------+---------
1 | 1
2 | 1.5
3 | 1.8333333333333335
10 | 2.928968253968254
100 | 5.1873775176396215
-------------------------- Extra (not needed to be a valid answer)
100000| 12.090146129863305
la source
k
est désactivée par une)Réponses:
MATL , 42 octets
Cela utilise une approche probabiliste (Monte Carlo). L'expérience est exécutée un grand nombre de fois, à partir de laquelle la probabilité est estimée. Le nombre de réalisations est sélectionné pour garantir que le résultat est correct jusqu'à la quatrième décimale avec une probabilité d'au moins 90%. Cependant, cela prend beaucoup de temps et beaucoup de mémoire. Dans le lien ci-dessous, le nombre de réalisations a été réduit d'un facteur 10 6 afin que le programme se termine dans un délai raisonnable; et seule la première décimale est garantie pour être précise avec une probabilité d'au moins 90%.
EDIT (29 juillet 2016): en raison de changements de langue,
6L
doit être remplacé par3L
. Le lien ci-dessous intègre cette modification.Essayez-le en ligne!
Contexte
Soit p la probabilité à calculer. L'expérience décrite dans le défi sera lancé pour un nombre n de fois. À chaque fois, soit vous gagnez le prix (« succès »), soit vous ne le gagnez pas. Soit N le nombre de succès. La probabilité souhaitée peut être estimée à partir de N et n . Plus n est grand, plus l'estimation sera précise. La question clé est de savoir comment sélectionner n pour remplir avec la précision souhaitée, à savoir, pour garantir qu'au moins 90% des fois l'erreur sera inférieure à 10 -4 .
Les méthodes de Monte Carlo peuvent être
Dans la deuxième catégorie, une méthode couramment utilisée consiste à fixer N (nombre souhaité de succès) et à continuer de simuler jusqu'à ce que ce nombre de succès soit atteint . Ainsi, n est aléatoire. Cette technique, appelée échantillonnage binomial inverse ou Monte Carlo binomial négatif , présente l'avantage de pouvoir limiter la précision de l'estimateur. Pour cette raison, il sera utilisé ici.
Plus précisément, avec Monte Carlo binomial négatif x = ( N -1) / ( n -1) est un estimateur sans biais de p ; et la probabilité que x s'écarte de p de plus d'un rapport donné peut être supérieure. Selon l'équation (1) de cet article (notez également que les conditions (2) sont remplies), prendre N = 2,75 · 10 8 ou plus garantit que p / x appartient à l'intervalle [1.0001, 0.9999] avec au moins 90% probabilité. En particulier, cela implique que x est correct jusqu'à la 4ème décimale avec au moins 90% de probabilité, comme souhaité.
Explication du code
Le code utilise N =
3e8
pour enregistrer un octet. Notez que faire de nombreuses simulations prendrait beaucoup de temps. Le code dans le lien utilise N =300
, qui s'exécute dans un laps de temps plus raisonnable (moins de 1 minute dans le compilateur en ligne pour les premiers cas de test); mais cela garantit seulement que la première décimale est correcte avec une probabilité d'au moins 90%.la source
Pyth, 34 octets
Suite de tests
Définit une fonction récursive mémorisée déterministe
g
prenant n , k comme arguments.g 1000 500
renvoie0.0018008560286627952
dans environ 18 secondes (non inclus dans la suite de tests ci-dessus car il expire l'interpréteur en ligne).Une traduction approximative de Python 3 serait
la source
JavaScript (ES6), 65 octets
Mais ne l'essayez pas avec les gros chiffres; même f (30, 10) prend un temps considérable.
la source