Pólya urna flip and roll


13

Dichiarazione problema

Pólya sta di nuovo giocando con la sua urna e vuole che tu lo aiuti a calcolare alcune probabilità.

In questo esperimento di urna Pólya ha un'urna che inizialmente contiene 1 perlina rossa e 1 blu.

Per ogni iterazione, raggiunge e recupera una perlina, quindi controlla il colore e posiziona la perlina nell'urna.

Poi lancia una moneta buona, se la moneta atterra teste inserirà nell'urna una discreta quantità di tiri dado a 6 facce dello stesso tallone colorato, se atterra le code rimuoverà metà del numero dello stesso tallone colorato dall'urna ( Usando la divisione intera - quindi se il numero di perline del colore selezionato è dispari, rimuoverà (c-1)/2dove c è il numero di perline di quel colore)

Dato un numero intero n ≥ 0 e un decimale r> 0, si dà la probabilità a 2 cifre decimali che il rapporto tra i colori delle perline dopo n iterazioni sia maggiore o uguale a r nel numero più breve di byte.

Un esempio di iterazioni:

Lascia (x, y) definire l'urna in modo tale che contenga x perline rosse e y perline blu.

Iteration    Urn       Ratio
0            (1,1)     1
1            (5,1)     5        //Red bead retrieved, coin flip heads, die roll 4
2            (5,1)     5        //Blue bead retrieved, coin flip tails
3            (3,1)     3        //Red bead retrieved, coin flip tails
4            (3,4)     1.333... //Blue bead retrieved, coin flip heads, die roll 3

Come si può vedere, il rapporto r è sempre ≥ 1 (quindi è maggiore del rosso o del blu diviso per il minore)

Casi test:

Consenti a F (n, r) di definire l'applicazione della funzione per n iterazioni e un rapporto di r

F(0,5) = 0.00
F(1,2) = 0.50
F(1,3) = 0.42
F(5,5) = 0.28
F(10,4) = 0.31
F(40,6.25) = 0.14

Questo è il golf del codice, quindi vince la soluzione più breve in byte.


Sento che esiste una formula per questo ...
Incarnazione dell'ignoranza

Qualcosa a che fare con i binomiali beta forse, ma potrebbe essere più lungo scriverlo
Dati scaduti

dipende dalla lingua; R e Mathematica potrebbero essere in grado di farlo in modo efficiente.
Giuseppe,

Risposte:


6

JavaScript (ES7),  145 ... 129 124  123 byte

Accetta input come (r)(n). Questa è una soluzione ingenua che esegue effettivamente l'intera simulazione.

r=>g=(n,B=s=0,R=0,h=d=>++d<7?h(d,[0,d].map(b=>g(n,B/-~!!b,R/-~!b)&g(n,B+b,R+d-b))):s/24**-~n)=>n--?h``:s+=~B<=r*~R|~R<=r*~B

Provalo online!

Troppo lento per gli ultimi 2 casi di test.

Commentate

r =>                    // r = target ratio
g = (                   // g is a recursive function taking:
  n,                    //   n = number of iterations
  B =                   //   B = number of blue beads, minus 1
  s = 0,                //   s = number of times the target ratio was reached
  R = 0,                //   R = number of red beads, minus 1
  h = d =>              //   h = recursive function taking d = 6-sided die value
    ++d < 7 ?           // increment d; if d is less than or equal to 6:
      h(                //   do a recursive call to h:
        d,              //     using the new value of d
        [0, d].map(b => //     for b = 0 and b = d:
          g(            //       do a first recursive call to g:
            n,          //         leave n unchanged
            B / -~!!b,  //         divide B by 2 if b is not equal to 0
            R / -~!b    //         divide R by 2 if b is equal to 0
          ) & g(        //       do a second recursive call to g:
            n,          //         leave n unchanged
            B + b,      //         add b blue beads
            R + d - b   //         add d - b red beads
          )             //       end of recursive calls to g
        )               //     end of map()
      )                 //   end of recursive call to h
    :                   // else (d > 6):
      s / 24 ** -~n     //   stop recursion and return s / (24 ** (n + 1))
) =>                    // body of g:
  n-- ?                 //   decrement n; if n was not equal to 0:
    h``                 //     invoke h with d = [''] (coerced to 0)
  :                     //   else:
    s +=                //     increment s if:
      ~B <= r * ~R |    //       either (-B-1) <= r*(-R-1), i.e. (B+1)/(R+1) >= r
      ~R <= r * ~B      //       or     (-R-1) <= r*(-B-1), i.e. (R+1)/(B+1) >= r

Mi piace molto questa risposta, ho scoperto che per risolvere i casi di test successivi avevo bisogno di aggiungere codice per unire le stesse probabilità di rapporto. Quindi non mi sorprende che sia troppo lento
Dati scaduti

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.