ギャンブラーの偽りのサイコロ


26

ギャンブラーの誤fallは認知バイアスであり、しばしば発生したことが将来発生する可能性が低く、しばらく発生しなかったものはすぐに発生する可能性が高いと誤って予想します。あなたの仕事は、これの特定のバージョンを実装することです。

チャレンジの説明

1から6までのランダムな整数を返す関数を作成します。キャッチ:関数が最初に実行されるとき、結果は均一(1%以内)である必要がありますが、以降の各呼び出しは、以前にロールされた回数が少ない値を優先してスキューされます。具体的な詳細は次のとおりです。

  • ダイは、これまでに生成された数のカウントを記憶しています。
  • 各結果は次の式で重み付けされます:countmaxcountdie+1
    • たとえば、これまでのロールカウントが 1、0、3、2、1、0場合、重みは 3、4、1、2、3、4になります。つまり、よりを振る可能性が4倍高い。[1,03210][341234]23
    • 式は、ロール結果がと同じように重み付けされることを意味することに注意してください。[abcdef][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 $番目の数の分布に最初の$ k-1 $数を与える必要があることを明示的かつ正確に指定します。
JiK

@JiK私は同意しません。その引数は、真のランダムではなく、PRNGを使用する他のコードに対して使用できるためです。私の提案非常に単純なものです、PRNGです。
ファックス

@JiKあなたが理論上の分布について話していると仮定すると、それはそうです。測定された分布は、統計的有意性を持つのに十分な大きさの$ k $に対して必要な1%以内です。
ファックス

1
@Faxランダムソースには少なくとも65535の期間がないため、この問題に十分なPRNGではありません。また、「測定された分布」の意味がわかりません。
JiK

回答:


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何ですか?(コードを読みにくくすることは別として!)
ロビンライダー

@RobinRyder私の元々のアイデアは関数を使用すること、TまたはF関数の内部でしたと思います。グローバルな割り当てが必要だと気づいたら、変更するのが面倒でした。
ジュゼッペ


1
@ Xi'an作業を開始しました!しかし、packageを使用すると、バイトカウントが高すぎますpawl
ロビンライダー

6

Pythonの3112 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,=およびdrop [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+''

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

どうやって?

これはかなり単純で、おそらく最適ではない実装であり、説明されているようにシミュレーションを実行します。

CsmaバツCC+1


3

APL(Dyalog Unicode)、32 バイトSBCS

間隔インデックスの代わりにレプリケートを使用して-4バイト。

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

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

現在の分布を引数として取り、結果のダイスロールを印刷し、更新された分布を返す関数として定義されます。TIOでの最初の実行は[0,0,0,0,0,0]、から始まる100回の呼び出しで、2回目の実行は1で大きく偏り[0,100,100,100,100,100]、最後の実行は同じ方法で6に大きく偏っています。


3

Perl 6、31バイト

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

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

すべての重みが1であるものから開始して、現在の重量分布をBagHashとして受け入れます。分布はその場で変更されます。

BagHash pickメソッドは、関連する重みを使用してランダムにキーを選択します。そのキーの重みは1つ減ります。その重みがそれによってゼロにされる場合、++«.{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
)

これは、jsの最大配列長であるw2 32 -1の長さを超えると最終的に爆発しますが、32ビットint配列2 32 -1の長さは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Ṭ+ɼṛƊ

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

別の方法として、選択した番号を返し、レジスタ内のカウントリストを追跡するniladicリンクがあります。

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