给定一个公平的硬币作为输入,产生任何特定的不公平结果


13

使用不公平的硬币很容易生成一个公平的硬币,但是反之则很难完成。

您的程序将收到一个数字X(介于0和1之间,包括0和1),作为输入。输入不能简单地硬编码为源代码中间的数字。然后,它必须返回一个数字:a 1的概率为X0否则为X。

您的程序仅允许在源代码中使用一种形式的随机数生成器:(int(rand(2))或等效形式),它以相等的概率返回零或一。您可以在代码中随意包含或访问此函数多次。您还必须自己提供功能作为代码的一部分。

您的程序不允许使用任何其他可以用作随机数生成功能的随机数生成功能或外部源(例如时间和日期功能)。它还无法访问任何外部文件或将作业传递给外部程序。

这是代码高尔夫,最短的答案胜出。


输入采用什么形式?如果我们保证它是给定大小的IEEE-754浮点数,那么实际上很简单。
彼得·泰勒

Answers:


4

Perl,37个42个字符

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

将任意概率作为命令行参数。建立一个统一的随机数$d,并将其与输入进行比较。

较早的52 char解决方案

$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的步长运行了100,000次[0,1]概率的程序,并与random.random() < desiredProbability使用以下脚本进行了比较:gist.github.com/3656877它们完美匹配i.imgur.com/Hr8uE.png
Matt

虽然,正如预期的那样,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个

校验

让我们看看是否f[.53]真的在1大约53%的时间内产生了该值。每次测试都会计算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

从左至右,一次一位:

如果RandomInteger []返回1,则答案= 1,

否则,如果第二个RandomInteger []返回0,则答案= 0,

否则,如果第三个RandomInteger []返回0,则答案= 0,

其他....

如果在测试完所有数字后仍然没有答案,则答案= 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,则当coinflip变为0时,返回0。否则,递归于2p;。假设正确,则获得1的总概率为2p或的一半p
  • 如果输入概率p大于1/2,则当coinflip出现1时,返回1。否则,递归2p-1; 假设正确,则获得0的总概率为1-(2p-1)或的一半1-p

为了使它更短,我们从随机的coinflip开始,在任一分支中,它都会有一半的时间被返回。如果coinflip与我们应返回的情况不匹配,请用对2p模1 递归的结果替换它。(即,当p小于1/2时,替换为1;当p大于1/2 时,替换为1 ,请替换为0。这等效于替换⌈1-2p⌉。)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.