Gambacy's Fallacy Dice


26

L'errore del giocatore è un pregiudizio cognitivo in cui ci aspettiamo erroneamente che le cose che si sono verificate spesso abbiano meno probabilità di accadere in futuro e le cose che non si sono verificate da un po 'di tempo avranno maggiori probabilità di accadere presto. Il tuo compito è implementare una versione specifica di questo.

Spiegazione della sfida

Scrivi una funzione che restituisce un numero intero casuale compreso tra 1 e 6, inclusi. Il problema: la prima volta che viene eseguita la funzione, il risultato dovrebbe essere uniforme (entro l'1%), tuttavia ogni chiamata successiva sarà distorta a favore di valori che sono stati lanciati meno volte in precedenza. I dettagli specifici sono i seguenti:

  • Il dado ricorda i conteggi dei numeri generati finora.
  • Ogni risultato è ponderato con la seguente formula: countmun'X-countdioe+1
    • Ad esempio, se il tiro conta finora è [1,0,3,2,1,0] , i pesi saranno [3,4,1,2,3,4] , vale a dire che si sarà 4 volte più probabilità di ottenere un 2 che un 3 .
    • Si noti che la formula indica che un risultato di rollio di [a,b,c,d,e,f] è ponderato come [a+n,b+n,c+n,d+n,e+n,f+n]

Regole e presupposti

  • Si applicano le regole I / O standard e le lacune vietate
  • I tiri di dado non dovrebbero essere deterministici. (ad esempio, utilizzare un PRNG con seeding da una fonte volatile, in quanto è generalmente disponibile come incorporato).
  • La tua fonte casuale deve avere un periodo di almeno 65535 o essere vera casualità.
  • Le distribuzioni devono essere entro l'1% per pesi fino a 255
    • Gli RNG a 16 bit sono abbastanza buoni da soddisfare entrambi i requisiti di cui sopra. La maggior parte degli RNG integrati sono sufficienti.
  • Puoi passare la distribuzione corrente fintanto che tale distribuzione è mutata dalla chiamata o la distribuzione post-lancio viene restituita insieme al tiro di dado. L'aggiornamento della distribuzione / conteggi fa parte di questa sfida .
  • È possibile utilizzare pesi anziché conteggi. Nel fare ciò, ogni volta che un peso scende a 0, tutti i pesi dovrebbero aumentare di 1 per ottenere lo stesso effetto della memorizzazione dei conteggi.
    • È possibile utilizzare questi pesi come ripetizioni di elementi in un array.

In bocca al lupo. Possano i byte essere sempre a tuo favore.


Sembra che tu possa rispettare tutte le regole e le scappatoie vietate iniziando con un numero casuale n, quindi emettendo (n ++% 6).
Fax

2
@Fax Questo problema specifica in modo esplicito ed esatto quale dovrebbe essere la distribuzione del numero $ k $ th con i primi numeri $ k-1 $. La tua idea dà ovviamente la distribuzione sbagliata per il secondo numero dato il primo numero.
JiK

@JiK Non sono d'accordo, poiché tale argomento potrebbe essere utilizzato contro qualsiasi altro codice che utilizza un PRNG anziché un vero casuale. La mia proposta è un PRNG, anche se molto semplicistico.
Fax

@JiK Supponendo che tu stia parlando di distribuzione teorica, cioè. La distribuzione misurata rientra nell'1% richiesto per $ k $ abbastanza grande da avere un significato statistico.
Fax,

1
@Fax La tua fonte casuale non ha un periodo di almeno 65535, quindi non è un PRNG sufficiente per questo problema. Inoltre non capisco cosa intendi per "distribuzione misurata".
JiK

Risposte:


12

R , 59 byte

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

Provalo online!

Mantiene i conteggi T, che viene quindi trasformato per essere utilizzato come weightsargomento in sample(che quindi molto probabilmente li normalizza per riassumere 1).

L' [<<-operatore viene utilizzato per assegnare un valore aT in uno degli ambienti padre (in questo caso, l'unico ambiente padre è .GlobalEnv).


2
Buon uso dell'assegnazione globale. Qualche motivo per cui hai chiamato la tua variabile T? (Oltre a rendere il codice più difficile da leggere!)
Robin Ryder,

@RobinRyder Penso che la mia idea originale fosse quella di utilizzare la funzione internamente To Finternamente, e quindi ero troppo pigro per cambiarlo una volta capito che avevo bisogno di un incarico globale.
Giuseppe,

3
@RobinRyder: sono sorpreso che tu non stia proponendo una soluzione Wang-Landau!
Xi'an,

1
@ Xi'an ho iniziato a lavorare su uno! Ma il conteggio dei byte era troppo alto quando si utilizzava il pacchetto pawl.
Robin Ryder

6

Python 3 , 112 99 byte

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)

Provalo online!

Spiegazione

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

Modifica: salvato 13 byte. Grazie attinat !



@attinat È possibile rilasciare 2 byte utilizzando la tupla decompressione ( c,=e rilascio [0]). Vale anche la pena notare che choicesè Python
3.6+

5

05AB1E , 13 byte

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

Provalo online!

Prende l'elenco dei conteggi come input. Emette il rotolo e i nuovi conteggi.

Spiegazione:

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 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+''

Provalo online!

Come?

Questa è un'implementazione piuttosto ingenua e molto probabilmente non ottimale che esegue la simulazione come descritto.

CSiomun'X(C)-Cio+1


3

APL (Dyalog Unicode) , 32 byte SBCS

-4 byte usando replicare anziché indice intervallo.

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

Provalo online!

Definita come una funzione che accetta la distribuzione corrente come argomento, stampa il tiro di dado risultante e restituisce la distribuzione aggiornata. La prima corsa su TIO è di 100 invocazioni a partire da [0,0,0,0,0,0], la seconda è fortemente distorta verso 1 con [0,100,100,100,100,100], e l'ultima corsa è fortemente distorta verso 6 nello stesso modo.


3

Perl 6 , 31 byte

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

Provalo online!

Accetta l'attuale distribuzione del peso come BagHash, iniziando da uno in cui tutti i pesi sono 1. La distribuzione è mutata sul posto.

Il pickmetodo BagHash seleziona una chiave a caso usando i pesi associati; il peso di quella chiave viene quindi diminuito di uno. Se tale peso viene quindi azzerato, ++«.{1..6}aumenta i pesi di tutti i numeri 1-6.



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)

Spiegazione

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
)

Nota che alla fine esploderà se wsupera una lunghezza di 2 32 -1, che è la lunghezza massima dell'array in js, ma probabilmente raggiungerai un limite di memoria prima di allora, considerando un array int a 32 bit 2 32 -1 long è 16GiB e alcuni browser (la maggior parte?) Non ti consentono di utilizzare più di 4GiB.


2

Perl 6 , 49 byte

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

Provalo online!

Prende i rotoli precedenti come Bag (multiset). Restituisce il nuovo rotolo e la nuova distribuzione.

Spiegazione

{                                            }  # 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

Pyth , 22 20 byte

Xt
hOs.e*]kh-eSQbQQ1

Provalo online!

L'input è le frequenze precedenti come un elenco, produce il roll successivo e le frequenze aggiornate separate da una nuova riga.

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

Gelatina , 12 byte

’ạṀJx$X,Ṭ+¥¥

Provalo online!

Un collegamento monadico che accetta un singolo argomento, l'elenco di conteggio corrente e restituisce un elenco del numero scelto e l'elenco di conteggi aggiornato.

Gelatina , 18 byte

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

Provalo online!

In alternativa, ecco un link niladico che restituisce il numero scelto e tiene traccia dell'elenco dei conteggi nel registro.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.