赌徒的谬误骰子


26

赌徒的谬误是一种认知偏见,我们错误地期望将来发生的事情不太可能在将来发生,而一段时间内未发生的事情在不久之后更可能发生。您的任务是实现特定版本。

挑战说明

编写一个函数,返回一个介于1到6之间(含1和6)的随机整数。问题是:第一次运行该函数时,结果应该是统一的(在1%以内),但是,每个后续调用都将偏向于那些以前滚动次数较少的值。具体细节如下:

  • 骰子记得到目前为止生成的数字计数。
  • 每个结果加权以下公式:countmaxcountdie+1
    • 例如,如果卷数到目前为止是[1,0,3,2,1,0],权重将是[3,4,1,2,3,4],也就是说,你将4倍的可能性滚23
    • 请注意,该公式表示[a,b,c,d,e,f]的滚动结果的权重与[a+n,b+n,c+n,d+n,e+n,f+n]

规则与假设

  • 适用标准I / O规则和禁止的漏洞
  • 模切辊不应确定。(即,使用从易失性源中植入的PRNG,通常作为内置源使用。)
  • 您的随机来源的周期必须至少为65535,或者是真正的随机性。
  • 重量不得超过255,分配范围必须在1%以内
    • 16位RNG足以满足以上两个要求。大多数内置的RNG足够了。
  • 您可以传递当前分布,只要该分布被调用突变或后卷分布在冲模卷旁边返回即可。更新分配/计数是此挑战的一部分
  • 您可以使用权重而不是计数。这样做时,每当权重降至0时,所有权重都应增加1,以达到与存储计数相同的效果。
    • 您可以将这些权重用作数组中元素的重复。

祝好运。愿字节永远对您有利。


看来您可以遵循所有规则和被禁止的漏洞,方法是从一个随机数n开始,然后输出(n ++%6)。
传真

2
@Fax这个问题明确指定了第一个$ k-1 $数字应该正确分配第k个数字的分布。您的想法显然是给定第一个数字的第二个数字分配错误。
JiK

@JiK我不同意,因为该参数可用于使用PRNG而不是真正随机的任何其他代码。我的建议 PRNG,尽管它很简单。
传真

@JiK假设您正在谈论理论分布。对于足够具有统计意义的$ k $,测得的分布在要求的1%以内。
传真

1
@Fax您的随机源的周期至少为65535,因此PRNG不足以解决此问题。我也不明白您所说的“按比例分配”是什么意思。

Answers:


12

R,59个字节

function(){T[o]<<-T[o<-sample(6,1,,max(T)-T+1)]+1
o}
T=!1:6

在线尝试!

将计数保持在中T,然后将其转换为用作weights参数sample(然后很可能将其归一化为1)。

[<<-操作者用于将值分配给T在父环境(在这种情况下,唯一的父环境中的一个.GlobalEnv)。


2
很好地使用全局分配。有什么理由叫您的变量T?(除了使代码更难阅读!)
Robin Ryder

@RobinRyder我认为我最初的想法是在函数内部使用T或使用它F,然后当我意识到需要全局分配时,我就懒得更改它。
朱塞佩

3
@RobinRyder:我很惊讶您没有提出Wang-Landau解决方案!
西安

1
@西安我确实开始研究一个!但是使用package时,字节数太高了pawl
罗宾·赖德

6

Python 3中112个 99字节

from random import*
def f(C=[0]*6):c=choices(range(6),[1-a+max(C)for a in C])[0];C[c]+=1;print(c+1)

在线尝试!

说明

# we only need the "choice" function
from random import*

      # C, the array that holds previous choices, is created once when the function is defined
      # and is persisted afterwards unless the function is called with a replacement (i.e. f(C=[0,1,2,3,4,5]) instead of f() )
      C=[0]*6
# named function
def f(.......):
                  # generate weights
                  [1-a+max(C)for a in C]
# take the first item generated using built-in method
c=choices(range(6),......................)[0]
    # increment the counter for this choice
    C[c]+=1
    # since the array is 0-indexed, increase the number by 1 for printing
    print(c+1)

编辑:保存了13个字节。谢谢,attinat



@attinat您可以使用元组拆包(c,=和dropping [0])删除2个字节。另外值得注意的choices是Python 3.6+
409_Conflict

5

05AB1E,13个字节

Z>αāDrÅΓΩ=Q+=

在线尝试!

将计数列表作为输入。输出滚动和新计数。

说明:

Z                 # maximum
 >                # plus 1
  α               # absolute difference (vectorizes)
                  # the stack now has the list of weights
ā                 # range(1, length(top of stack)), in this case [1..6]
 D                # duplicate
  r               # reverse the entire stack
   ÅΓ             # run-length decode, using the weights as the run lengths
     Ω            # pick a random element
                  # the stack is now: counts, [1..6], random roll
=                 # output the roll without popping
 Q                # test for equality, vectorizing
  +               # add to the counts
   =              # output the new counts

3

JavaScript(ES8),111个字节

_=>++C[C.map((v,i)=>s+=''.padEnd(Math.max(...C)-v+1,i),s=''),n=s[Math.random()*s.length|0]]&&++n;[,...C]=1e6+''

在线尝试!

怎么样?

这是一个相当幼稚的方法,并且很可能是次优的,它执行了所述的仿真。

Csimax(C)Ci+1


3

APL(Dyalog Unicode),32 字节SBCS

使用复制而不是间隔索引的-4字节。

{1∘+@(⎕←(?∘≢⌷⊢)(1+⍵-⍨⌈/⍵)/⍳6)⊢⍵}

在线尝试!

定义为将当前分布作为参数,打印最终的模具辊并返回更新的分布的函数。在TIO上的第一次运行是从开始的100次调用[0,0,0,0,0,0],第二次运行以严重偏向1 [0,100,100,100,100,100],而最后一次运行以相同的方式严重偏向6。


3

Perl 6,31个字节

{--.{$/=.pick}||++«.{1..6};$/}

在线尝试!

接受当前的重量分布作为BagHash,从所有权重均为1的值开始。分布将就地进行突变。

BagHash pick方法使用关联的权重随机选择一个密钥。然后,该键的权重将减一。如果该权重由此为零,则++«.{1..6}增加所有数字1-6的权重。



2

Javascript(ES6 +),97个字节

d=[1,2,3,4,5,6]
w=[...d]
r=x=>(i=~~(Math.random()*w.length),k=w[i],w.concat(d.filter(x=>x!=k)),k)

说明

d=[1,2,3,4,5,6]                   // basic die
w=[...d]                          // weighted die
r=x=>(                            // x is meaningless, just saves 1 byte vs ()
  i=~~(Math.random()*w.length),   // pick a random face of w
  k=w[i],                         // get the value of that face
  w.concat(d.filter(x=>x!=k)),    // add the faces of the basic die that aren't the value
                                  // we just picked to the weighted die
  k                               // return the value we picked
)

请注意,如果w超过2 32 -1 的长度(这是js中的最大数组长度),此操作最终会崩溃,但是考虑到32位int数组2 32 -1 long为,则可能在此之前达到内存限制。16GiB,某些(大多数?)浏览器不允许您使用超过4GiB的内容。


2

Perl 6,49个字节

{($!=roll (1..6 X=>1+max 0,|.{*})∖$_:),$_$!}

在线尝试!

将先前的卷作为袋(多组)。返回新的卷和新的分布。

说明

{                                            }  # Anon block taking
                                                # distribution in $_
                     max 0,|.{*}  # Maximum count
                   1+             # plus one
           1..6 X=>  # Pair with numbers 1-6
          (                     )∖$_  # Baggy subtract previous counts
     roll                            :  # Pick random element from Bag
 ($!=                                 )  # Store in $! and return
                                       ,$_$!  # Return dist with new roll

1

Pyth22 20字节

Xt
hOs.e*]kh-eSQbQQ1

在线尝试!

输入是列表中的前一个频率,输出下一个滚动和以换行符分隔的更新频率。

Xt¶hOs.e*]kh-eSQbQQ1   Implicit: Q=eval(input())
                       Newline replaced with ¶
      .e         Q     Map elements of Q, as b with index k, using:
             eSQ         Max element of Q (end of sorted Q)
            -   b        Subtract b from the above
           h             Increment
        *]k              Repeat k the above number of times
                       Result of the above is nested weighted list
                       e.g. [1,0,3,2,1,0] -> [[0, 0, 0], [1, 1, 1, 1], [2], [3, 3], [4, 4, 4], [5, 5, 5, 5]]
     s                 Flatten
    O                  Choose random element
   h                   Increment
  ¶                    Output with newline
 t                     Decrement
X                 Q1   In Q, add 1 to the element with the above index
                       Implicit print

1

果冻,12字节

’ạṀJx$X,Ṭ+¥¥

在线尝试!

单子链接,它采用一个参数,当前计数列表,并返回所选数字和更新后的计数列表的列表。

果冻,18字节

0x6+ɼṀ_®‘Jx$XṬ+ɼṛƊ

在线尝试!

作为替代方案,这是一条尼拉德链接,该链接返回所选的数字并跟踪寄存器中的计数列表。

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.