Dados de Falácia do Jogador

26

A falácia do jogador é um viés cognitivo em que, por engano, esperamos que coisas que ocorreram com frequência sejam menos prováveis ​​de ocorrer no futuro e que coisas que não ocorreram há algum tempo sejam mais prováveis ​​de acontecer em breve. Sua tarefa é implementar uma versão específica disso.

Explicação do desafio

Escreva uma função que retorne um número inteiro aleatório entre 1 e 6, inclusive. O problema: na primeira vez em que a função é executada, o resultado deve ser uniforme (dentro de 1%); no entanto, cada chamada subsequente será inclinada em favor de valores que foram lançados menos vezes anteriormente. Os detalhes específicos são os seguintes:

  • O dado lembra as contagens de números gerados até agora.
  • Cada resultado é ponderado com a seguinte fórmula:countmaxcountdie+1
    • Por exemplo, se a contagem de rolos até agora for , os pesos serão , ou seja, você será 4 vezes mais chances de rolar um que um .[1,0,3,2,1,0][3,4,1,2,3,4]23
    • Observe que a fórmula significa que um resultado de rolagem de é ponderado da mesma forma que[a,b,c,d,e,f][a+n,b+n,c+n,d+n,e+n,f+n]

Regras e premissas

  • Regras de E / S padrão e brechas proibidas se aplicam
  • Os rolos de matriz não devem ser determinísticos. (ou seja, use um PRNG semeado a partir de uma fonte volátil, como normalmente está disponível como embutido.)
  • Sua fonte aleatória deve ter um período de pelo menos 65535 ou ser uma aleatoriedade verdadeira.
  • As distribuições devem estar dentro de 1% para pesos de até 255
    • RNGs de 16 bits são bons o suficiente para atender aos dois requisitos acima. A maioria dos RNGs embutidos é suficiente.
  • Você pode passar na distribuição atual desde que essa distribuição seja alterada pela chamada ou a distribuição pós-roll seja retornada ao lado do rolo de molde. Atualizar a distribuição / contagens faz parte desse desafio .
  • Você pode usar pesos em vez de contagens. Ao fazer isso, sempre que um peso cai para 0, todos os pesos devem aumentar em 1 para obter o mesmo efeito que as contagens de armazenamento.
    • Você pode usar esses pesos como repetições de elementos em uma matriz.

Boa sorte. Que os bytes estejam sempre a seu favor.

Beefster
fonte
Parece que você pode cumprir todas as regras e brechas proibidas iniciando com um número aleatório n e, em seguida, exibindo (n ++% 6).
Fax
2
@Fax Esse problema especifica explicitamente e exatamente qual a distribuição do número $ k $ th que deve receber os primeiros números $ k-1 $. Sua ideia fornece obviamente a distribuição incorreta para o segundo número, dado o primeiro número.
JiK
@JiK Eu discordo, pois esse argumento pode ser usado contra qualquer outro código que use um PRNG em vez de verdadeiro aleatório. Minha proposta é um PRNG, embora muito simplista.
Fax
@JiK Supondo que você esteja falando sobre distribuição teórica, isso é. A distribuição medida está dentro dos 1% exigidos por um valor de $ k $ grande o suficiente para ter significância estatística.
Fax
1
@Fax Sua fonte aleatória não possui um período de pelo menos 65535, portanto, não é um PRNG suficiente para esse problema. Também não entendo o que você quer dizer com "distribuição medida".
JiK

Respostas:

12

R , 59 bytes

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

Experimente online!

Mantém as contagens T, que são transformadas para serem usadas como weightsargumento para sample(que provavelmente as normaliza para somar 1).

O [<<-operador é usado para atribuir um valor a Tum dos ambientes pai (nesse caso, o único ambiente pai é .GlobalEnv).

Giuseppe
fonte
2
Bom uso da atribuição global. Alguma razão para você ter chamado sua variável T? (Além de tornar o código mais difícil de ler!)
Robin Ryder
@RobinRyder Acho que minha idéia original era usar Tou Finternamente a função, e fiquei com preguiça de alterá-la quando percebi que precisava de uma atribuição global.
Giuseppe
3
@RobinRyder: Estou surpreso que você não esteja propondo uma solução Wang-Landau!
Xian
1
@ Xi'an eu comecei a trabalhar em um! Mas a contagem de bytes era muito alta ao usar o pacote 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)

Experimente online!

Explicação

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

Editar: salvou 13 bytes. Obrigado, attinat !

Triggernometria
fonte
1
99 bytes
attinat 17/05
@attinat Você pode soltar 2 bytes usando a descompactação da tupla ( c,=e soltando [0]). Também vale a pena notar que choicesé Python 3.6+
409_Conflict
5

05AB1E , 13 bytes

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

Experimente online!

Toma a lista de contagens como entrada. Produz o rolo e as novas contagens.

Explicação:

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
Grimmy
fonte
3

JavaScript (ES8), 111 bytes

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

Experimente online!

Quão?

Essa é uma implementação bastante ingênua e provavelmente subótima que executa a simulação conforme descrito.

Nós acompanhar as contagens em . Em cada rolo, construímos uma cadeia que consiste em cada fieira repetido vezes, e escolher uma entrada aleatória em com uma distribuição uniforme.Csimax(C)Ci+1

Arnauld
fonte
3

APL (Dyalog Unicode) , SBCS de 32 bytes

-4 bytes usando replicar em vez de índice de intervalo.

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

Experimente online!

Definida como uma função que usa a distribuição atual como argumento, imprime o rolo de matriz resultante e retorna a distribuição atualizada. A primeira execução no TIO é de 100 invocações, começando com [0,0,0,0,0,0], a segunda execução é fortemente inclinada para 1 com [0,100,100,100,100,100]e a última execução é fortemente inclinada para 6 da mesma maneira.

voidhawk
fonte
3

Perl 6 , 31 bytes

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

Experimente online!

Aceita a distribuição de peso atual como um BagHash, começando com um onde todos os pesos são 1. A distribuição é alterada no local.

O pickmétodo BagHash seleciona uma chave aleatoriamente usando os pesos associados; o peso dessa chave é então decrementado em um. Se esse peso for zero, ++«.{1..6}incrementa os pesos de todos os números de 1 a 6.

Sean
fonte
2

Javascript (ES6 +), 97 bytes

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)

Explicação

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
)

Observe que isso eventualmente explodirá se wexceder o comprimento de 2 32 -1, que é o comprimento máximo da matriz em js, mas você provavelmente atingirá um limite de memória antes disso, considerando que uma matriz int de 32 bits com comprimento de 32 -1 é 16GiB e alguns (a maioria?) Navegadores não permitem que você use mais do que 4GiB.

asgallant
fonte
2

Perl 6 , 49 bytes

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

Experimente online!

Toma os rolos anteriores como um saco (multiset). Retorna o novo rolo e a nova distribuição.

Explicação

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

Pitão , 22 20 bytes

Xt
hOs.e*]kh-eSQbQQ1

Experimente online!

A entrada é as frequências anteriores como uma lista, produz o próximo rolo e as frequências atualizadas separadas por uma nova linha.

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
fonte
1

Gelatina , 12 bytes

’ạṀJx$X,Ṭ+¥¥

Experimente online!

Um link monádico que utiliza um único argumento, a lista de contagens atual e retorna uma lista do número escolhido e a lista de contagens atualizada.

Gelatina , 18 bytes

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

Experimente online!

Como alternativa, aqui está um link niládico que retorna o número escolhido e acompanha a lista de contagens no registro.

Nick Kennedy
fonte