Dés de fausseté du joueur


26

Le sophisme du joueur est un biais cognitif où nous nous attendons à tort à ce que les événements qui se sont produits soient moins susceptibles de se produire à l'avenir et les événements qui ne se sont pas produits depuis longtemps soient plus susceptibles de se produire bientôt. Votre tâche consiste à implémenter une version spécifique de cela.

Explication du défi

Écrivez une fonction qui renvoie un entier aléatoire compris entre 1 et 6, inclus. Le hic: la première fois que la fonction est exécutée, le résultat doit être uniforme (à moins de 1%), cependant, chaque appel suivant sera faussé en faveur de valeurs qui ont été roulées moins de fois auparavant. Les détails spécifiques sont les suivants:

  • Le dé se souvient du nombre de nombres générés jusqu'à présent.
  • Chaque résultat est pondéré avec la formule suivante:countmaxcountdie+1
    • Par exemple, si le nombre de rouleaux jusqu'à présent est , les poids seront , c'est-à-dire que vous serez 4 fois plus susceptibles de lancer un qu'un .[1,0,3,2,1,0][3,4,1,2,3,4]23
    • Notez que la formule signifie qu'un résultat de roulis de est pondéré de la même façon que[a,b,c,d,e,f][une+n,b+n,c+n,+n,e+n,F+n]

Règles et hypothèses

  • Les règles d'E / S standard et les failles interdites s'appliquent
  • Les lancers ne doivent pas être déterministes. (c.-à-d. utiliser un PRNG issu d'une source volatile, comme cela est généralement disponible en tant que module intégré.)
  • Votre source aléatoire doit avoir une période d'au moins 65535 ou être un vrai hasard.
  • Les distributions doivent être inférieures à 1% pour les poids jusqu'à 255
    • Les RNG 16 bits sont suffisamment bons pour répondre aux deux exigences ci-dessus. La plupart des RNG intégrés sont suffisants.
  • Vous pouvez transmettre la distribution actuelle tant que cette distribution est mutée par l'appel ou que la distribution post-roll est renvoyée avec le dé. La mise à jour de la distribution / des comptages fait partie de ce défi .
  • Vous pouvez utiliser des poids au lieu de comptes. Ce faisant, chaque fois qu'un poids tombe à 0, tous les poids doivent augmenter de 1 pour obtenir le même effet que le stockage des comptes.
    • Vous pouvez utiliser ces poids comme répétitions d'éléments dans un tableau.

Bonne chance. Que les octets soient toujours en votre faveur.


Il semble que vous pouvez respecter toutes les règles et les failles interdites en commençant par un nombre aléatoire n, puis en sortant (n ++% 6).
Télécopie

2
@Fax Ce problème spécifie explicitement et exactement quelle distribution du $ k $ ème nombre doit être donnée aux premiers $ k-1 $ nombres. Votre idée donne évidemment la mauvaise distribution pour le deuxième nombre étant donné le premier nombre.
JiK

@JiK Je ne suis pas d'accord, car cet argument pourrait être utilisé contre tout autre code utilisant un PRNG par opposition à true random. Ma proposition est un PRNG, quoique très simpliste.
Fax

@JiK En supposant que vous parliez de distribution théorique, bien sûr. La distribution mesurée se situe dans les 1% requis pour un $ k $ suffisamment grand pour avoir une signification statistique.
Fax

1
@Fax Votre source aléatoire n'a pas une période d'au moins 65535, donc ce n'est pas un PRNG suffisant pour ce problème. Je ne comprends pas non plus ce que vous entendez par "distribution mesurée".
JiK

Réponses:


12

R , 59 octets

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

Essayez-le en ligne!

Conserve les décomptes dans T, qui est ensuite transformé pour être utilisé comme weightsargument sample(qui les normalise alors très probablement pour additionner 1).

L' [<<-opérateur est utilisé pour attribuer une valeur à Tdans l'un des environnements parents (dans ce cas, le seul environnement parent est .GlobalEnv).


2
Belle utilisation de l'affectation globale. Une raison pour laquelle vous avez appelé votre variable T? (En plus de rendre le code plus difficile à lire!)
Robin Ryder

@RobinRyder Je pense que mon idée originale était d'utiliser la fonction Tou en Finterne, puis j'étais trop paresseux pour la changer une fois que j'ai réalisé que j'avais besoin d'une affectation globale.
Giuseppe

3
@RobinRyder: Je suis surpris que vous ne proposiez pas de solution Wang-Landau!
Xi'an

1
@ Xi'an J'ai commencé à travailler sur un! Mais le nombre d'octets était beaucoup trop élevé lors de l'utilisation de package pawl.
Robin Ryder

6

Python 3 , 112 99 octets

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)

Essayez-le en ligne!

Explication

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

Modifier: enregistré 13 octets. Merci, attinat !



@attinat Vous pouvez supprimer 2 octets en utilisant le déballage ( c,=et la suppression [0]) de tuple . Il convient également de noter que choicesPython 3.6+
409_Conflict

5

05AB1E , 13 octets

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

Essayez-le en ligne!

Prend la liste des comptes en entrée. Sort le rouleau et les nouveaux comptes.

Explication:

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 octets

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

Essayez-le en ligne!

Comment?

Il s'agit d'une implémentation plutôt naïve et probablement sous-optimale qui effectue la simulation comme décrit.

CsjemuneX(C)-Cje+1


3

APL (Dyalog Unicode) , 32 octets SBCS

-4 octets utilisant la réplication au lieu de l'index d'intervalle.

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

Essayez-le en ligne!

Défini comme une fonction qui prend la distribution actuelle comme argument, imprime le jet de dé résultant et renvoie la distribution mise à jour. La première exécution sur TIO est de 100 appels commençant par [0,0,0,0,0,0], la deuxième exécution est fortement biaisée vers 1 avec [0,100,100,100,100,100], et la dernière exécution est fortement biaisée vers 6 de la même manière.


3

Perl 6 , 31 octets

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

Essayez-le en ligne!

Accepte la distribution de poids actuelle en tant que BagHash, en commençant par celle où tous les poids sont 1. La distribution est mutée sur place.

La pickméthode BagHash sélectionne une clé au hasard en utilisant les poids associés; le poids de cette clé est alors décrémenté de un. Si ce poids est ainsi mis à zéro, ++«.{1..6}incrémente les poids de tous les nombres 1-6.



2

Javascript (ES6 +), 97 octets

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)

Explication

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
)

Notez que cela finira par exploser s'il wdépasse une longueur de 2 32 -1, qui est la longueur maximale du tableau en js, mais vous atteindrez probablement une limite de mémoire avant cela, étant donné qu'un tableau int 32 bits de 2 32 -1 est long 16GiB, et certains navigateurs (la plupart?) Ne vous permettront pas d'utiliser plus de 4GiB.


2

Perl 6 , 49 octets

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

Essayez-le en ligne!

Prend les rouleaux précédents comme un sac (multiset). Renvoie le nouveau rouleau et la nouvelle distribution.

Explication

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

Xt
hOs.e*]kh-eSQbQQ1

Essayez-le en ligne!

L'entrée est les fréquences précédentes sous forme de liste, les sorties du rouleau suivant et les fréquences mises à jour séparées par une nouvelle ligne.

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

Gelée , 12 octets

’ạṀJx$X,Ṭ+¥¥

Essayez-le en ligne!

Un lien monadique qui prend un seul argument, la liste de comptage actuelle, et renvoie une liste du nombre choisi et la liste de comptage mise à jour.

Gelée , 18 octets

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

Essayez-le en ligne!

Comme alternative, voici un lien niladique qui retourne le nombre choisi et garde une trace de la liste de comptage dans le registre.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.