あなたが20面のサイコロを持っているとしましょう。あなたはそのサイコロを転がし始め、最終的に20個すべての値を転がす前に数十回転がさなければなりません。20個すべての値が50%の確率で表示されるまでに、いくつのロールが必要ですか。そして、n
私がすべてのn
面を転がす前に、何面のサイコロを振る必要がありますか?
いくつかの調査の結果、ロール後にすべての値をロールする可能性を計算するための式が存在することがわかりました。n
r
P(r, n) = n! * S(r, n) / n**r
ここで、は第2種のスターリング数をS(a, b)
示し、n個のオブジェクト(各ロール)のセットをk個の空でないサブセット(各サイド)に分割する方法の数を示します。
また、が50%以上の最小のに対応するOEISシーケンス(これをと呼びます)も見つかります。課題は、このシーケンスのth項をできるだけ速く計算することです。R(n)
r
P(r, n)
n
チャレンジ
- 与えられ
n
、検索最小r
場所P(r, n)
以上で0.5
50%。 - コードは理論的には負でない整数
n
を入力として処理する必要がありますが、テストするのはの範囲でのみ1 <= n <= 1000000
です。 - スコアリングのために、我々は実行するために必要な合計時間かかりなります
R(n)
入力に1
スルー10000
。 - あなたのソリューションは、私たちのバージョンを実行して、正しいかどうかをチェックする
R(n)
かどうかを確認するために、あなたの出力にP(your_output, n) >= 0.5
し、P(your_output - 1, n) < 0.5
あなたの出力は、実際に最も小さいすなわちことを、r
与えられたためn
。 S(a, b)
ソリューションでは任意の定義を使用できます。ウィキペディアには、ここで役立ついくつかの定義があります。S(a, b)
計算P(r, n)
するものや直接計算するものを含め、ソリューションに組み込みを使用できます。- 最大1000個の値
R(n)
と100万個のスターリング数をハードコードできますが、どちらもハードリミットではなく、値を上げたり下げたりする説得力のある引数を作成できる場合は変更できます。 - と探しているの
r
間n
で可能な限りすべてをチェックする必要はありませんが、どこかだけでなくr
、最小のものを見つける必要があります。r
r
P(r, n) >= 0.5
- プログラムでは、Windows 10で自由に実行できる言語を使用する必要があります。
ソリューションをテストするコンピュータの仕様は次のとおりi7 4790k, 8 GB RAM
です。テスト用のコンピューターを提供してくれた@DJMcMayhemに感謝します。参考のために独自の非公式のタイミングを自由に追加してください。ただし、公式のタイミングは、DJがテストできるようになり次第提供されます。
テストケース
n R(n)
1 1
2 2
3 5
4 7
5 10
6 13
20 67 # our 20-sided die
52 225 # how many cards from a huge uniformly random pile until we get a full deck
100 497
366 2294 # number of people for to get 366 distinct birthdays
1000 7274
2000 15934
5000 44418
10000 95768
100000 1187943
1000000 14182022
質問や提案がありましたらお知らせください。幸運と最適化!