Фальшиві кістки азартних гравців


26

Помилковість азартного гравця - це когнітивний ухил, коли ми помилково очікуємо, що речі, які траплялися часто, мають меншу ймовірність у майбутньому, а речі, які не відбулися через деякий час, мають більшу ймовірність скоро відбутися. Ваше завдання - реалізувати конкретну версію цього.

Пояснення виклику

Напишіть функцію, яка повертає випадкове ціле число між 1 і 6 включно. Захоплення: при першому запуску функції результат повинен бути рівномірним (в межах 1%), однак кожен наступний виклик буде перекошений на користь значень, які раніше були прокручені менше. Конкретні деталі:

  • Штамб пам'ятає кількість генерованих до цього часу чисел.
  • Кожен результат зважується за такою формулою: countmaxcountdie+1
    • Наприклад, якщо нарахування кількості рулонів досі [1,0,3,2,1,0] , ваги будуть [3,4,1,2,3,4] , тобто, ви будете У 4 рази більше шансів скотити 2 ніж 3 .
    • Зауважимо, що формула означає, що результат згортання [a,b,c,d,e,f] зважується так само, як [a+n,b+n,c+n,d+n,e+n,f+n]

Правила та припущення

  • Застосовуються стандартні правила вводу / виводу та заборонені лазівки
  • Валики рулонів не повинні бути детермінованими. (тобто використовувати PRNG, посіяний з енергонезалежного джерела, як правило, він є вбудованим.)
  • Ваш випадковий джерело повинен мати період принаймні 65535 або бути справжньою випадковістю.
  • Розподіл повинен бути в межах 1% для ваг до 255
    • 16-бітні РГГ досить хороші для задоволення обох вищезазначених вимог. Більшість вбудованих РНГ є достатніми.
  • Ви можете передавати поточний розподіл до тих пір, поки цей дистрибутив буде вимкнено або вимкнено під час виклику, або після повернення після повернення. Оновлення розподілу / підрахунків є частиною цього завдання .
  • Ви можете використовувати ваги замість лічильників. При цьому кожен раз, коли вага падає до 0, всі ваги повинні збільшуватися на 1, щоб досягти такого ж ефекту, як зберігання рахунків.
    • Ви можете використовувати ці ваги як повторення елементів у масиві.

Удачі. Нехай байти коли-небудь будуть на вашу користь.


Здається, ви можете дотримуватися всіх правил і заборонених лазів, починаючи з випадкового числа n, а потім виводити (n ++% 6).
Факс

2
@Fax Ця проблема чітко вказує та саме, який розподіл $ k $ th числа має бути надано першим $ k-1 $ числам. Ваша ідея очевидно дає неправильний розподіл для другого числа з огляду на перше число.
JiK

@JiK Я не згоден, оскільки цей аргумент може використовуватися проти будь-якого іншого коду, який використовує PRNG на відміну від істинного випадкового. Моя пропозиція - PRNG, хоч і дуже спрощена.
Факс

@JiK Припустимо, що ви говорите про теоретичний розподіл, тобто. Виміряний розподіл знаходиться в межах необхідного 1% для $ k $ достатньо великого, щоб мати статистичну значимість.
Факс

1
@Fax У вашому випадковому джерелі немає періоду принаймні 65535, тому це не PRNG, достатній для цієї проблеми. Також я не розумію, що ви маєте на увазі під "вимірюваним розподілом".
JiK

Відповіді:


12

R , 59 байт

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

Спробуйте в Інтернеті!

Зберігає підрахунки T, які потім перетворюються на використання в якості weightsаргументу sample(що потім, швидше за все, нормалізує їх для підрахунку 1).

[<<-Оператор використовується для присвоєння значення Tв одній з батьківських середовищ (в даному випадку, єдиний батько середу .GlobalEnv).


2
Гарне використання глобального завдання. З якої причини ви назвали свою змінну T? (Крім того, щоб зробити код важче читати!)
Робін Райдер

@RobinRyder Я вважаю, що моя первісна ідея полягала в тому, щоб використовувати функцію Tабо Fвнутрішньо функціонувати, і тоді я лінувався змінювати її, як тільки зрозумів, що мені потрібно глобальне завдання.
Джузеппе

3
@RobinRyder: Я здивований, що ти не пропонуєш рішення Ван-Ландау!
Сіань

1
@ Xi'an Я почав працювати над одним! Але кількість байтів була занадто великою при використанні пакету pawl.
Робін Райдер

6

Python 3 , 112 99 байт

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)

Спробуйте в Інтернеті!

Пояснення

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

Редагувати: збережено 13 байт. Спасибі, аттинат !



@attinat Ви можете скинути 2 байти, використовуючи розпакування кортежу ( c,=і скидання [0]). Також варто зазначити, що choicesце Python 3.6+
409_Conflict

5

05AB1E , 13 байт

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

Спробуйте в Інтернеті!

Приймає список підрахунків як вхідні. Виводить рулон та нові рахунки.

Пояснення:

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 байт

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

Спробуйте в Інтернеті!

Як?

Це досить наївна і, швидше за все, неоптимальна реалізація, яка виконує моделювання, як описано.

Ссiмах(С)-Сi+1


3

APL (Dyalog Unicode) , 32 байти SBCS

-4 байти, використовуючи репліку замість інтервального індексу.

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

Спробуйте в Інтернеті!

Визначений як функція, яка приймає поточний дистрибутив як аргумент, друкує отриманий ролик і повертає оновлений дистрибутив. Перший запуск на TIO - це 100 викликів, починаючи з [0,0,0,0,0,0], другий запуск сильно зміщений до 1 з [0,100,100,100,100,100], а останній запуск сильно зміщений до 6 таким же чином.


3

Perl 6 , 31 байт

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

Спробуйте в Інтернеті!

Приймає поточний розподіл ваги як BagHash, починаючи з такого, де всі ваги є 1. Розподіл мутується на місці.

Метод BagHash pickвибирає ключ навмання, використовуючи відповідні ваги; вага цього ключа потім зменшується на одиницю. Якщо ця вага тим самим дорівнює нулю, ++«.{1..6}збільшуємо ваги всіх чисел 1-6.



2

Javascript (ES6 +), 97 байт

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)

Пояснення

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
)

Зауважте, що в підсумку це підірветься, якщо wперевищить довжину 2 32 -1, що є максимальною довжиною масиву в js, але ви, ймовірно, досягнете межі пам'яті до цього часу, враховуючи, що 32-бітний масив int 2 32 -1 довгий 16GiB та деякі (більшість?) Браузерів не дозволять вам використовувати більше 4GiB.


2

Perl 6 , 49 байт

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

Спробуйте в Інтернеті!

Приймає попередні рулони як мішок (мультисет). Повертає новий ролик та новий дистрибутив.

Пояснення

{                                            }  # 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 байт

Xt
hOs.e*]kh-eSQbQQ1

Спробуйте в Інтернеті!

Вхід - це попередні частоти у списку, виводиться наступний список і оновлені частоти, розділені новим рядком.

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

Желе , 12 байт

’ạṀJx$X,Ṭ+¥¥

Спробуйте в Інтернеті!

Монадічне посилання, яке бере один аргумент, поточний список рахунків, і повертає список обраного числа та оновлений список підрахунків.

Желе , 18 байт

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

Спробуйте в Інтернеті!

В якості альтернативи, ось niladic-посилання, яке повертає вибране число та відстежує список підрахунків у реєстрі.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.