Dados de falacia del jugador

26

La falacia del jugador es un sesgo cognitivo en el que erróneamente esperamos que las cosas que ocurrieron a menudo tengan menos probabilidades de ocurrir en el futuro y que las cosas que no ocurrieron en un tiempo tengan más probabilidades de suceder pronto. Su tarea es implementar una versión específica de esto.

Explicación del desafío

Escriba una función que devuelva un entero aleatorio entre 1 y 6, inclusive. El problema: la primera vez que se ejecuta la función, el resultado debe ser uniforme (dentro del 1%), sin embargo, cada llamada posterior se sesgará a favor de los valores que se han lanzado menos veces anteriormente. Los detalles específicos son los siguientes:

  • El dado recuerda los recuentos de números generados hasta ahora.
  • Cada resultado se pondera con la siguiente fórmula:countmaxcountdie+1
    • Por ejemplo, si el rollo cuenta hasta ahora es , los pesos serán , es decir que usted será 4 veces más probabilidades de sacar un que un .[1,0,3,2,1,0][3,4,1,2,3,4]23
    • Tenga en cuenta que la fórmula significa que un resultado de la tirada de se pondera igual que[a,b,c,d,e,f][a+n,b+n,c+n,d+n,e+n,f+n]

Reglas y suposiciones

  • Se aplican las reglas estándar de E / S y las lagunas prohibidas
  • Los dados no deben ser deterministas. (es decir, use un PRNG sembrado de una fuente volátil, ya que normalmente está disponible como un generador incorporado).
  • Su fuente aleatoria debe tener un período de al menos 65535 o ser verdadera aleatoriedad.
  • Las distribuciones deben estar dentro del 1% para pesos de hasta 255
    • Los RNG de 16 bits son lo suficientemente buenos como para cumplir con los requisitos anteriores. La mayoría de los RNG incorporados son suficientes.
  • Puede pasar la distribución actual siempre que esa distribución esté mutada por la llamada o la distribución posterior al lanzamiento se devuelva junto con la tirada del dado. Actualizar la distribución / conteos es parte de este desafío .
  • Puede usar pesas en lugar de conteos. Al hacerlo, cada vez que un peso cae a 0, todos los pesos deberían aumentar en 1 para lograr el mismo efecto que el conteo de almacenamiento.
    • Puede usar estos pesos como repeticiones de elementos en una matriz.

Buena suerte. Que los bytes estén siempre a tu favor.

Carne de res
fuente
Parece que puede cumplir con todas las reglas y lagunas prohibidas comenzando con un número aleatorio n, luego generando (n ++% 6).
Fax
2
@Fax Este problema especifica de manera explícita y exacta cuál debe ser la distribución del número $ k $ th en los primeros números $ k-1 $. Su idea obviamente proporciona la distribución incorrecta para el segundo número dado el primer número.
JiK
@JiK No estoy de acuerdo, ya que ese argumento podría usarse contra cualquier otro código que use un PRNG en lugar de un verdadero aleatorio. Mi propuesta es un PRNG, aunque muy simplista.
Fax
@JiK Asumiendo que estás hablando de distribución teórica, claro. La distribución medida está dentro del 1% requerido para un $ k $ lo suficientemente grande como para tener significación estadística.
Fax
1
@Fax Su fuente aleatoria no tiene un período de al menos 65535, por lo que no es un PRNG suficiente para este problema. Además, no entiendo lo que quiere decir con "distribución medida".
JiK

Respuestas:

12

R , 59 bytes

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

Pruébalo en línea!

Mantiene los recuentos T, que luego se transforman para usarse como weightsargumento sample(lo que probablemente los normaliza para sumar 1).

El [<<-operador se utiliza para asignar un valor a Tuno de los entornos principales (en este caso, el único entorno principal es .GlobalEnv).

Giuseppe
fuente
2
Buen uso de la asignación global. ¿Alguna razón por la que llamaste variable T? (¡Además de hacer que el código sea más difícil de leer!)
Robin Ryder
@RobinRyder Creo que mi idea original era usar To Finternamente la función, y luego fui demasiado vago para cambiarla una vez que me di cuenta de que necesitaba una asignación global.
Giuseppe
3
@RobinRyder: ¡Me sorprende que no propongas una solución Wang-Landau!
Xi'an
1
@ Xi'an ¡Empecé a trabajar en uno! Sin embargo, el número de bytes era demasiado alto cuando se utiliza el paquete 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)

Pruébalo en línea!

Explicación

# 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: Guardado 13 bytes. Gracias, attinat !

Triggernometry
fuente
1
99 bytes
attinat
@attinat Puede soltar 2 bytes usando el desempaquetado de tuplas ( c,=y soltando [0]). También vale la pena señalar que choiceses Python 3.6+
409_Conflict
5

05AB1E , 13 bytes

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

Pruébalo en línea!

Toma la lista de recuentos como entrada. Emite el rollo y los nuevos recuentos.

Explicación:

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

Pruébalo en línea!

¿Cómo?

Esta es una implementación bastante ingenua y probablemente subóptima que realiza la simulación como se describe.

Realizamos un seguimiento de los recuentos en . En cada rollo, construimos una cadena que consiste en cada dado repitió veces y elegir una entrada al azar en allí con una distribución uniforme.Csimax(C)Ci+1

Arnauld
fuente
3

APL (Dyalog Unicode) , SBCS de 32 bytes

-4 bytes usando replicar en lugar de índice de intervalo.

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

Pruébalo en línea!

Definido como una función que toma la distribución actual como argumento, imprime la tirada resultante y devuelve la distribución actualizada. La primera ejecución en TIO tiene 100 invocaciones comenzando [0,0,0,0,0,0], la segunda ejecución está fuertemente sesgada hacia 1 con [0,100,100,100,100,100], y la última ejecución está fuertemente sesgada hacia 6 de la misma manera.

halcón vacío
fuente
3

Perl 6 , 31 bytes

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

Pruébalo en línea!

Acepta la distribución de peso actual como BagHash, comenzando con una donde todos los pesos son 1. La distribución está mutada en el lugar.

El pickmétodo BagHash selecciona una clave al azar utilizando los pesos asociados; el peso de esa tecla se reduce en uno. Si ese peso se hace así cero, ++«.{1..6}incrementa los pesos de todos los números 1-6.

Sean
fuente
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)

Explicación

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
)

Tenga en cuenta que esto eventualmente explotará si wexcede una longitud de 2 32 -1, que es la longitud máxima de la matriz en js, pero probablemente alcanzará un límite de memoria antes de eso, teniendo en cuenta que una matriz de 32 bits int 32 32 -1 es 16GiB, y algunos navegadores (¿la mayoría?) No le permitirán usar más de 4GiB.

asgallant
fuente
2

Perl 6 , 49 bytes

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

Pruébalo en línea!

Toma los rollos anteriores como una bolsa (conjunto múltiple). Devuelve el nuevo rollo y la nueva distribución.

Explicación

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

Pyth , 22 20 bytes

Xt
hOs.e*]kh-eSQbQQ1

Pruébalo en línea!

La entrada es las frecuencias anteriores como una lista, emite el siguiente rollo y las frecuencias actualizadas separadas por una nueva línea.

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

Jalea , 12 bytes

’ạṀJx$X,Ṭ+¥¥

Pruébalo en línea!

Un enlace monádico que toma un solo argumento, la lista de conteo actual, y devuelve una lista del número elegido y la lista de conteo actualizada.

Jalea , 18 bytes

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

Pruébalo en línea!

Como alternativa, aquí hay un enlace niládico que devuelve el número elegido y realiza un seguimiento de la lista de conteo en el registro.

Nick Kennedy
fuente