Моя местная глава ACM раздает дверные призы людям, которые приходят на собрания. Однако вы получите больше шансов на победу, если решите головоломку программирования (но я всегда решаю эту головоломку). Таким образом, некоторые люди имеют 1 запись, а другие - 2. Но подождите! Программа лотереи работает не путем добавления другой записи, когда кто-то решает головоломку. Вместо этого он отслеживает количество «жизней» человека, уменьшая его, если этот человек выбирается на каждом проходе алгоритма случайной выборки. Так что это работает так:
Doorknob: 1. xnor: 2. Justin: 2. Alex: 1. Dennis: 2.
Затем программа случайным образом выбирает одно из значений [Doorknob, xnor, Justin, Alex, Dennis]
, уменьшает число (скажем, выбирает Justin
):
Doorknob: 1. xnor: 2. Justin: 1. Alex: 1. Dennis: 2.
И повторяется. Если чье-то количество «жизней» перейдет к 0
(давайте выберем Justin
снова), они будут удалены из списка:
Doorknob: 1. xnor: 2. Alex: 1. Dennis: 2.
Это продолжается до тех пор, пока не останется один человек; этот человек является победителем.
Теперь реальный вопрос, какова вероятность того, что я бы выиграл?
Вам будут предоставлены два входа:
n
, Это количество людей, вступивших в вызовk
, Это количество людей (из техn
), которые имеют 2 жизни. Этот номер всегда включает вас.
Так что, если бы у меня была функция p
и позвонил p(10, 5)
, это было бы вероятностью выиграть приз, если всего 10 человек, 5 из которых имеют только 1 жизнь, тогда как 5 (включая вас) имеют 2 жизни.
Ожидается, что вы получите вероятность выигрыша либо точно, либо в виде десятичной дроби. Во всяком случае, ответы должны быть с точностью до и в том числе 4 - го знака после запятой после десятичной точки. Независимо от того, округлили ли вы эту цифру или нет, зависит от вас.
Ваше решение может быть рандомизированным решением, которое с высокой вероятностью выводит ответ с точностью до 4- го знака после запятой . Вы можете предположить, что используемая вами встроенная ГСЧ действительно случайная, и она должна вывести правильный ответ с вероятностью не менее 90%.
Кроме того, ваш код должен работать только для n, k <= 1000
, хотя я предоставил тестовые примеры больше, чем для любопытных.
Тестовые случаи
Примечание: некоторые из них являются общими формулами.
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
Для еще нескольких проверок сделайте p(n, 1) * n
следующее:
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
источник
k
она отключена одним)Ответы:
MATL , 42 байта
Это использует вероятностный (Монте-Карло) подход. Эксперимент проводится большое количество раз, из которых оценивается вероятность. Число реализаций выбирают так, чтобы гарантировать , что результат является правильным до четвертого знака после запятой с вероятностью не менее 90%. Однако это занимает очень много времени и много памяти. В приведенной ниже ссылке количество реализаций было сокращено в 10 6 раз, так что программа заканчивается в разумные сроки; и только первый десятичный знак гарантированно будет точным с вероятностью не менее 90%.
РЕДАКТИРОВАТЬ (29 июля 2016 г.): в связи с изменением языка
6L
необходимо заменить на3L
. Ссылка ниже включает эту модификацию.Попробуйте онлайн!
Фон
Пусть p обозначает вероятность, которую нужно вычислить. Эксперимент, описанный в задании, будет проводиться несколько раз n . Каждый раз либо вы выигрываете приз (« успех »), либо нет. Пусть N будет количеством успехов. Желаемая вероятность может быть оценена из N и n . Чем больше n , тем точнее будет оценка. Ключевой вопрос заключается в том, как выбрать n для выполнения с желаемой точностью, а именно, чтобы гарантировать, что по крайней мере в 90% случаев ошибка будет меньше 10 -4 .
Методы Монте-Карло могут быть
Среди второй категории обычно используемый метод состоит в том, чтобы фиксировать N (желаемое количество успехов) и продолжать моделирование до тех пор, пока не будет достигнуто это количество успехов . Таким образом, n является случайным. Эта методика, называемая обратной биномиальной выборкой или отрицательной биномиальной Монте-Карло , имеет то преимущество, что точность оценки может быть ограничена. По этой причине он будет использован здесь.
В частности, с отрицательным биномиальным множителем Монте-Карло x = ( N −1) / ( n −1) является несмещенной оценкой p ; и вероятность того, что x отклонится от p более чем на заданное соотношение, может быть ограничена сверху. В соответствии с уравнением (1) в этой статье (обратите внимание также, что условия (2) выполняются), принимая N = 2,75 · 10 8 или более, гарантирует, что p / x принадлежит интервалу [1.0001, 0.9999] по меньшей мере на 90% вероятность. В частности, это означает, что x является правильным с точностью до 4-го знака после запятой с вероятностью не менее 90%, как желательно.
Код объяснил
Код использует N =
3e8
для сохранения одного байта. Обратите внимание, что выполнение этого большого количества симуляций заняло бы много времени. Код в ссылке использует N =300
, который выполняется в более разумное время (менее 1 минуты в онлайн-компиляторе для первых тестовых случаев); но это только гарантирует, что первое десятичное число является правильным с вероятностью не менее 90%.источник
Pyth, 34 байта
Тестирование
Определяет детерминированную запомненную рекурсивную функцию,
g
принимающую n , k в качестве аргументов.g 1000 500
возвращает0.0018008560286627952
примерно через 18 секунд (не входит в вышеуказанный набор тестов, потому что истекает время онлайн-переводчика).Примерный перевод Python 3 будет
источник
JavaScript (ES6), 65 байт
Не пытайтесь сделать это с большими числами; даже f (30, 10) занимает заметное количество времени.
источник