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.