Gambler's Fallacy Dice

26

Der Irrtum des Spielers ist eine kognitive Verzerrung, bei der wir fälschlicherweise davon ausgehen, dass Dinge, die in der Zukunft häufig aufgetreten sind, weniger wahrscheinlich sind und Dinge, die seit einiger Zeit nicht mehr aufgetreten sind, eher bald passieren werden. Ihre Aufgabe ist es, eine bestimmte Version davon zu implementieren.

Herausforderungserklärung

Schreiben Sie eine Funktion, die eine zufällige Ganzzahl zwischen 1 und 6 einschließlich zurückgibt. Der Haken: Wenn die Funktion zum ersten Mal ausgeführt wird, sollte das Ergebnis einheitlich sein (innerhalb von 1%). Jeder nachfolgende Aufruf wird jedoch zugunsten von Werten verschoben, die zuvor weniger oft gewürfelt wurden. Die spezifischen Details sind wie folgt:

  • Der Würfel merkt sich die Anzahl der bisher erzeugten Zahlen.
  • : Jedes Ergebnis wird mit der folgenden Formel gewichtet countmeinx-cOuntdiche+1
    • Wenn zum Beispiel die bisherigen Rollenzahlen [1,0,3,2,1,0] , sind die Gewichte [3,4,1,2,3,4] , das heißt, Sie sind es 4-mal häufiger eine 2 als eine 3 würfeln .
    • Beachten Sie, dass die Formel bedeutet, dass ein Rollergebnis von [ein,b,c,d,e,f] genauso gewichtet wird wie [ein+n,b+n,c+n,d+n,e+n,f+n]

Regeln und Annahmen

  • Es gelten Standard-E / A-Regeln und verbotene Regelungslücken
  • Die Rollen sollten nicht deterministisch sein. (Verwenden Sie also ein PRNG, das aus einer flüchtigen Quelle stammt, wie es normalerweise als eingebautes Produkt erhältlich ist.)
  • Ihre zufällige Quelle muss eine Periode von mindestens 65535 haben oder echte Zufälligkeit sein.
  • Die Verteilungen müssen bei Gewichten bis zu 255 innerhalb von 1% liegen
    • 16-Bit-RNGs sind gut genug, um beide oben genannten Anforderungen zu erfüllen. Die meisten eingebauten RNGs sind ausreichend.
  • Sie können die aktuelle Verteilung weitergeben, solange diese Verteilung entweder durch den Aufruf mutiert wird oder die Verteilung nach dem Wurf neben dem Würfelwurf zurückgegeben wird. Die Aktualisierung der Verteilung / Anzahl ist Teil dieser Herausforderung .
  • Sie können Gewichte anstelle von Zählungen verwenden. Wenn dabei ein Gewicht auf 0 fällt, sollten alle Gewichte um 1 erhöht werden, um den gleichen Effekt wie beim Speichern von Zählwerten zu erzielen.
    • Sie können diese Gewichte als Wiederholungen von Elementen in einem Array verwenden.

Viel Glück. Mögen die Bytes immer zu Ihren Gunsten sein.

Beefster
quelle
Anscheinend können Sie alle Regeln und verbotenen Lücken einhalten, indem Sie mit einer Zufallszahl n beginnen und dann (n ++% 6) ausgeben.
Fax
2
@Fax Dieses Problem gibt explizit und genau an, wie die Verteilung der $ k $ -ten Zahl mit den ersten $ k-1 $ -Nummern versehen werden soll. Ihre Idee ergibt offensichtlich die falsche Verteilung für die zweite Zahl mit der ersten Zahl.
JiK
@JiK Ich bin anderer Meinung, da dieses Argument gegen jeden anderen Code verwendet werden könnte, der ein PRNG im Gegensatz zu echtem Zufall verwendet. Mein Vorschlag ist ein PRNG, wenn auch ein sehr simpler.
Fax
@JiK Angenommen, Sie sprechen über die theoretische Verteilung. Die gemessene Verteilung liegt innerhalb der geforderten 1% für ein $ k $, das groß genug ist, um statistische Signifikanz zu haben.
Fax
1
@Fax Ihre zufällige Quelle hat keinen Zeitraum von mindestens 65535, daher reicht ein PRNG für dieses Problem nicht aus. Ich verstehe auch nicht, was Sie unter "gemessener Verteilung" verstehen.
JiK

Antworten:

12

R , 59 Bytes

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

Probieren Sie es online!

Behält die Zählungen bei T, die dann transformiert werden, um als weightsArgument für verwendet zu werden sample(wodurch sie höchstwahrscheinlich zur Summe normalisiert werden 1).

Der [<<-Operator wird verwendet, um Tin einer der übergeordneten Umgebungen einen Wert zuzuweisen (in diesem Fall ist dies die einzige übergeordnete Umgebung .GlobalEnv).

Giuseppe
quelle
2
Gute Verwendung der globalen Zuweisung. Haben Sie Ihre Variable aus irgendeinem Grund aufgerufen T? (Abgesehen davon, dass der Code schwieriger zu lesen ist!)
Robin Ryder
@RobinRyder Ich glaube, meine ursprüngliche Idee war, die Funktion zu verwenden Toder Fintern zu verwenden, und dann war ich zu faul, um sie zu ändern, als mir klar wurde, dass ich eine globale Zuweisung benötigte.
Giuseppe
3
@RobinRyder: Ich bin überrascht, dass Sie keine Wang-Landau-Lösung
Xi'an
1
@ Xi'an Ich habe angefangen, an einem zu arbeiten! Aber die Anzahl der Bytes war bei der Verwendung von package viel zu hoch pawl.
Robin Ryder
6

Python 3 , 112 99 Bytes

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)

Probieren Sie es online!

Erläuterung

# 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)

Bearbeiten: 13 Bytes gespeichert. Danke, Attinat !

Triggernometrie
quelle
1
99 Bytes
attinat
@attinat Sie können 2 Bytes löschen, indem Sie Tupel entpacken ( c,=und löschen [0]). Auch erwähnenswert , dass choicesist Python 3.6 oder höher
409_Conflict
5

05AB1E , 13 Bytes

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

Probieren Sie es online!

Nimmt die Liste der Zählungen als Eingabe. Gibt die Rolle und die neuen Zählwerte aus.

Erläuterung:

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
Grimmig
quelle
3

JavaScript (ES8), 111 Byte

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

Probieren Sie es online!

Wie?

Dies ist eine eher naive und höchstwahrscheinlich suboptimale Implementierung, die die beschriebene Simulation durchführt.

Csichmeinx(C)-Cich+1

Arnauld
quelle
3

APL (Dyalog Unicode) , 32 Byte SBCS

-4 Bytes unter Verwendung von Replikat anstelle von Intervallindex.

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

Probieren Sie es online!

Wird als eine Funktion definiert, die die aktuelle Verteilung als Argument verwendet, den resultierenden Würfelwurf druckt und die aktualisierte Verteilung zurückgibt. Der erste Lauf auf TIO beginnt mit 100 Aufrufen [0,0,0,0,0,0], der zweite Lauf ist stark auf 1 mit [0,100,100,100,100,100]und der letzte Lauf ist stark auf 6 in der gleichen Weise vorgespannt.

voidhawk
quelle
3

Perl 6 , 31 Bytes

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

Probieren Sie es online!

Akzeptiert die aktuelle Gewichtsverteilung als BagHash, beginnend mit einer, bei der alle Gewichte 1 sind. Die Verteilung wird an Ort und Stelle mutiert.

Die BagHash- pickMethode wählt einen Schlüssel nach dem Zufallsprinzip unter Verwendung der zugeordneten Gewichte aus. Das Gewicht dieses Schlüssels wird dann um eins verringert. Wenn dieses Gewicht dadurch zu Null gemacht wird, werden ++«.{1..6}die Gewichte aller Zahlen 1-6 inkrementiert.

Sean
quelle
2

Javascript (ES6 +), 97 Byte

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)

Erläuterung

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
)

Beachten Sie, dass dies irgendwann explodiert, wenn weine Länge von 2 32 -1 überschritten wird. Dies ist die maximale Array-Länge in js. Unter Berücksichtigung einer Länge von 32-Bit-Int-Arrays von 2 32 -1 werden Sie jedoch wahrscheinlich vorher an eine Speichergrenze stoßen 16GiB und einige (die meisten?) Browser lassen Sie nicht mehr als 4GiB verwenden.

asgallant
quelle
2

Perl 6 , 49 Bytes

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

Probieren Sie es online!

Nimmt die vorherigen Rollen als Beutel (Multiset). Gibt die neue Rolle und die neue Verteilung zurück.

Erläuterung

{                                            }  # 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
nwellnhof
quelle
1

Pyth , 22 bis 20 Bytes

Xt
hOs.e*]kh-eSQbQQ1

Probieren Sie es online!

Eingabe ist die vorherige Frequenz als Liste, Ausgabe der nächsten Rolle und der aktualisierten Frequenzen, getrennt durch einen Zeilenumbruch.

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
Sok
quelle
1

Gelee , 12 Bytes

’ạṀJx$X,Ṭ+¥¥

Probieren Sie es online!

Ein monadischer Link, der ein einzelnes Argument, die aktuelle Zählliste, verwendet und eine Liste der ausgewählten Nummer und der aktualisierten Zählliste zurückgibt.

Jelly , 18 Bytes

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

Probieren Sie es online!

Als Alternative gibt es hier einen Link, der die gewählte Nummer zurückgibt und die Zählerliste im Register verfolgt.

Nick Kennedy
quelle