入力として公正なコインを与え、特定の不公平な結果を生成します


13

不公平なコインを使用して公正なコインを生成するのは簡単ですが、その逆を達成するのはより困難です。

プログラムは、入力として1 つの数値X(0〜1を含む)を受け取ります。入力は、ソースコードの途中の数字として単純にハードコードされてはなりません。次に、1桁を返す必要があります。1確率がX0場合、それ以外の場合は。

プログラムは、ソースコードで1つの形式の乱数ジェネレーターint(rand(2))(または同等のもの)のみを使用できます。これは、等しい確率でゼロまたは1を返します。この関数は、コードに何度でも含めたり、アクセスしたりできます。また、コードの一部として自分で関数を提供する必要があります。

プログラムでは、乱数生成関数として機能する可能性のある他の乱数生成関数または外部ソース(時刻関数や日付関数など)を使用できません。また、外部ファイルにアクセスしたり、外部プログラムにジョブを渡すこともできません。

これはコードゴルフで、最短の回答が勝ちです。


入力はどのような形式を取りますか?指定されたサイズのIEEE-754浮動小数点数であることが保証されている場合、これは実際には非常に簡単です。
ピーターテイラー

回答:


4

Perl、37 42文字

($d/=2)+=rand>.5for%!;print$d/2<pop|0

コマンドライン引数として任意の確率を取ります。一様な乱数$dを作成し、入力と比較します。

以前の52文字ソリューション

$p=<>;do{$p*=2;$p-=($-=$p)}while$--(.5<rand);print$-

1
このソリューションを最適化するために6年後に戻ってきたことに感銘を受けました。
ミシャラヴロフ

3

Python、81文字

import random
print(sum(random.randint(0,1)*2**-i for i in range(9))<input()*2)+0

少しずれることもありますが、1%を超えることはありません。


私にとっては1%よりずっと良く見えます。私は0.01のステップであなたのプログラムに[0,1]の確率のために10万回を走ったとし、これを比較してrandom.random() < desiredProbability、このスクリプトを使用して:gist.github.com/3656877彼らは完全に一致i.imgur.com/Hr8uE.pngを
マット・

ただし、予想どおり、random.random() < xかなり高速です。
マット

3

Mathematica 165

合理化されていませんが、興味のあるアルゴリズムが見つかる場合があります。

d = RealDigits; r = RandomInteger;
f@n_ := If[(c = Cases[Transpose@{a = Join[ConstantArray[0, Abs[d[n, 2][[2]]]], d[n, 2][[1]]], 
         RandomInteger[1, {Length@a}]}, {x_, x_}]) == {}, r, c[[1, 1]]]

使用法

f[.53]

1

小切手

約53%の時間でf[.53]実際に値が生成されるかどうかを見てみましょう1。各テストは、10 ^ 4のサンプルの%を計算します。

このようなテストが50回実行され、平均されます。

Table[Count[Table[f[.53], {10^4}], 1]/10^4 // N, {50}]
Mean[%]

{0.5292、0.5256、0.5307、0.5266、0.5245、0.5212、0.5316、0.5345、0.5297、0.5334、0.5306、0.5288、0.528、0.5379、0.5293、0.5263、0.539、0.5322、0.5195、0.5208、0.5382、0.543、0.5336、0.5305、0.5303 、0.5297、0.5318、0.5243、0.5281、0.5361、0.5349、0.5308、0.5265、0.5309、0.5233、0.5345、0.5316、0.5376、0.5264、0.5269、0.5295、0.523、0.5294、0.5326、0.5316、0.5334、0.5165、0.5296、0.5266、0.5293 }

0.529798

結果のヒストグラム

ヒストグラム

説明(ネタバレ注意!)

.53のベース2表現は

.10000111101011100001010001111010111000010100011110110

左から右へ、一度に1桁ずつ進みます。

RandomInteger []が1を返す場合、answer = 1

それ以外の場合、2番目のRandomInteger []が0を返す場合、answer = 0、

その他3番目のRandomInteger []が0を返す場合、答えは0です。

そうしないと....

すべての数字がテストされたときに、まだ回答がない場合、answer = RandomInteger []。


1

Haskell、107文字:

import System.Random
g p|p>1=print 1|p<0=print 0|1>0=randomIO>>=g.(p*2-).f
f x|x=1|1>0=0.0
main=readLn>>=g

0

Wolfram言語(Mathematica)、42バイト

RandomInteger[]/.⌈1-2#⌉:>#0@Mod[2#,1]&

オンラインでお試しください!

これは再帰的なアプローチです。アルゴリズムは次のとおりです。

  • 入力確率pが1/2未満の場合、コインフリップが0になったときに0を返し2pます。それ以外の場合は、再帰します。正しさを想定し、1を得るための全体的な確率は半分のです2pp
  • 入力確率pが1/2より大きい場合、コインフリップが1になったときに1を返します。それ以外の場合は、再帰し2p-1ます。正しさを想定し、0を得るための全体的な確率は半分のです1-(2p-1)1-p

短くするために、ランダムなコインフリップから始めます。どちらのブランチでも、半分の時間で返されます。コインフリップが返されるはずのケースと一致しない場合2pは、モジュロ1 での再帰の結果で置き換えます(つまりp、1/2より小さい場合は1を、1 p/2より大きい場合は、0を置き換え⌈1-2p⌉ます。これは、置き換えと同等です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.