The gambler's fallacy is a cognitive bias where we mistakenly expect things that have occurred often to be less likely to occur in the future and things that have not occurred in a while to be more likely to happen soon. Your task is to implement a specific version of this.
Challenge Explanation
Write a function that returns a random integer between 1 and 6, inclusive. The catch: the first time the function is run, the outcome should be uniform (within 1%), however, each subsequent call will be skewed in favor of values that have been rolled fewer times previously. The specific details are as follows:
- The die remembers counts of numbers generated so far.
- Each outcome is weighted with the following formula: \$count_{max} - count_{die} + 1\$
- For instance, if the roll counts so far are \$[1, 0, 3, 2, 1, 0]\$, the weights will be \$[3, 4, 1, 2, 3, 4]\$, that is to say that you will be 4 times more likely to roll a \$2\$ than a \$3\$.
- Note that the formula means that a roll outcome of \$[a, b, c, d, e, f]\$ is weighted the same as \$[a + n, b + n, c + n, d + n, e + n, f + n]\$
Rules and Assumptions
- Standard I/O rules and banned loopholes apply
- Die rolls should not be deterministic. (i.e. use a PRNG seeded from a volatile source, as is typically available as a builtin.)
- Your random source must have a period of at least 65535 or be true randomness.
- Distributions must be within 1% for weights up to 255
- 16-bit RNGs are good enough to meet both the above requirements. Most built-in RNGs are sufficient.
- You may pass in the current distribution as long as that distribution is either mutated by the call or the post-roll distribution is returned alongside the die roll. Updating the distribution/counts is a part of this challenge.
- You may use weights instead of counts. When doing so, whenever a weight drops to 0, all weights should increase by 1 to achieve the same effect as storing counts.
- You may use these weights as repetitions of elements in an array.
Good luck. May the bytes be ever in your favor.