修复损坏的随机函数


18

朋友的计算机上有一个附加卡,该附加卡可生成一个从1到5(含1和5)的完美随机数。不幸的是,他们以某种方式将可乐洒在上面,现在它从1到4的所有数字仅生成2。幸运的是,随机性得以保留,但是2的概率为80%,5的概率为20%,并且没有生成1、3或4。使用此随机源(称为“随机源” BrokenRand()或类似名称),编写一个工作的随机数生成器,该生成器以与原始源相同的完全随机性,以相等的20%概率产生1到5个数字。

最短的程序获胜。BrokenRand由按人口统计选择的客户服务中心咨询机构公正地拨打最少电话的奖励积分,按年龄和性别(即我)细分。

Answers:


10

JavaScript-69个字符

这使用冯·诺依曼提取器生成无偏位;HotBits网站上也描述了通用算法。三个位用于形成一个从0到7的数字。所有5和5以上的数字都将被丢弃,其余的1将在打印之前加到每个数字上。我进行了模拟,以表明这没有严重的偏差

您需要提供自己的功能r()才能访问RNG。

 for(;;v<5&&alert(v+1))for(v=i=0;i<3;a-b&&(v*=2,v+=a<b,i++))b=r(a=r())

这确实做得很好!我喜欢您如何使增量值短路。
snmcdonald 2011年

您可以生成7位并提取3个随机数以减少对BrokenRand的调用,但这可能会花费更多笔触
gnibbler 2011年

5

Scala 79个字符:

// preparation: 
val r = util.Random 
def defektRNG = if (r.nextInt (5) == 0) 5 else 2 

(1 to 20).foreach (_ => print (" " + defektRNG))
// first impression:
// 2 2 2 2 2 2 2 5 2 2 5 2 2 2 5 2 2 2 2 2

def rnd : Int = { val k = (1 to 5).map (_ => defektRNG)
  if (k.sum == 13) k.findIndexOf (_ == 5) + 1 else rnd } 

// first impression:
(1 to 20).foreach (_ => print (" " + rnd))             
// 3 3 2 3 5 2 2 5 1 1 3 4 3 2 5 3 3 1 5 4
// control:
(1 to 50000).map (_ => rnd).groupBy (identity) .map (_._2.length) 
// scala.collection.immutable.Iterable[Int] = List(10151, 9997, 9971, 9955, 9926)

现在,对于真正的高尔夫,defetkRNG别名“ brokenRand”重命名为b。

def r:Int={val k=(1 to 5).map(_=>b)
if(k.sum==13)k.findIndexOf(_==5)+1 else r} 

工作原理:b通常返回2的序列。但是,如果您对b进行5次调用,那么您通常会以4x2和1x5结尾,这是第二大可能的事件,可以是5-2-2-2-2、2-5-2-2 -2、2-2-5-2-2、2-2-2-5-2和2-2-2-2-5。

它们的共同点是总和为4 * 2 + 5 = 13。前五个的索引可用于定义有效的随机数。如果大于或小于5,则重复大于或小于13。

“ rnd”或“ r”中的计数器可以显示平均需要多少个电话才能产生该号码。对于50 000个随机数,有121 200个调用r,这并不令人印象深刻。:)


3

> <>(鱼) -55字节

更新为在scala答案中使用与@user unknown相同的算法

<v?= d +&:i&+&:i&+&:i&+&:i&:i
 0
 > 1 + $ 5(?vnao;
 ^ <

它希望将损坏的生成器连接到stdin;这是我使用python脚本。该代码与当前的Fish规范匹配,但是我使用了旧解释器的修改版本

bash:$ for i in $(seq 1000); do ./bad_rand.py | ./myfish.py rand.fish; done >res.txt
bash:$ for i in $(seq 5); do echo -n "$i : "; grep -c $i res.txt; done
1 : 193
2 : 204
3 : 198
4 : 206
5 : 199

我会做一个更大的样本,但是速度很慢。


2

GolfScript,23个字节

答案很晚,但是因为这刚好出现在首页上...

0{;[{r}5*].5?)\5-,4-}do

使用与未知用户的Scala解决方案相同的算法。假设有偏的随机数生成器以名为GolfScript的子例程给出r;您可以自己定义合适的有偏RNG,例如:

{5rand!3*2+}:r;

这是一个快速测试,表明没有偏见。 不幸的是,在线GolfScript服务器有点慢,因此我不得不将演示缩减为仅100个样本,以使其按时完成。如果使用GolfScript解释器在本地运行测试,请尝试将100*to 1000*或什至增加10000*

(GolfScript服务器有时也会随机冻结并超时。如果发生这种情况,通常可以再试一次解决。它也与其他代码一起发生,并且仅在服务器上发生,而不是在我自己的计算机上发生,因此我有信心这是服务器的问题,而不是我的代码。)


-1

javascript,160个字符而不降低可读性, 也称为优化

function giveRandom(){
    var result = Math.floor(5 * Math.random()) + 1;
    while(BrockenRand() != 5){
        result = Math.floor(5 * Math.random()) + 1;
    }
    return result;
}

@ snmcdonald-其中一些不是拼写错误,这是通过仅批准(完全随机!)的完美随机生成器来改善js随机性的一种方法(结果完全是随机的!)20%的结果
www0z0k 2011

小心解释是什么BrockenBand()
Mateen Ulhaq 2011年

6
我认为您错过了重点
cthom06 2011年

@muntoo-含义BrockenRand
www0z0k 2011年

这样可以节省一些字节:function giveRandom(){return Math.ceil(Math.random()*5)}
user300375 '17
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.