폴리 야 항아리 플립 앤 롤


13

문제 설명

Pólya는 다시 그의 항아리를 가지고 놀았으며, 그는 당신이 그에게 확률을 계산하도록 도와 주길 원합니다.

이 항아리 실험에서 Pólya는 처음에 1 개의 빨간색과 1 개의 파란색 구슬을 포함하는 항아리를 가지고 있습니다.

매번 반복 할 때마다 그는 구슬에 도달하여 구슬을 가져온 다음 색을 검사하여 구슬을 다시 항아리에 넣습니다.

그런 다음 공정한 동전을 뒤집습니다. 동전이 땅에 떨어지면 같은 색깔의 구슬로 된 6 면체 다이 롤 금액을 항아리에 넣습니다. 꼬리가 떨어지면 항아리에서 같은 색깔의 구슬의 절반을 제거합니다. 정수 나누기를 사용하여-선택한 색상의 구슬 수가 홀수이면 (c-1)/2c는 해당 색상의 구슬 수입니다.

정수 n ≥ 0 및 소수 r> 0이 주어지면 n 반복 후 비드의 색상 간 비율이 가장 짧은 바이트 수에서 r보다 크거나 같은 확률을 소수점 이하 2 자리까지 줄 수 있습니다.

반복 세트의 예 :

(x, y)가 x 붉은 구슬과 y 푸른 구슬을 포함하도록 항아리를 정의하게하십시오.

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

알 수 있듯이 비율 r은 항상 1 이상입니다 (따라서 빨강 또는 파랑 중 큰 쪽이 작은 쪽)

테스트 사례 :

F (n, r)이 n 개의 반복에 대한 함수의 적용과 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

이것은 코드 골프이므로 바이트 단위의 최단 솔루션이 이깁니다.


나는 이것에 대한 공식이 있다고 생각합니다.
— 무지의 구체화

베타 이항식과 관련이있을 수도 있지만, 그것을 작성하는 것이 더 길 수 있습니다.
— Expired Data

언어에 따라 다릅니다. R과 Mathematica는 효율적으로 할 수 있습니다.
— Giuseppe

답변:


6

자바 스크립트 (ES7),  145 ...  129124123 바이트

로 입력을 (r)(n)받습니다. 실제로 전체 시뮬레이션을 수행하는 순진한 솔루션입니다.

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

온라인으로 사용해보십시오!

마지막 2 개의 테스트 사례에 비해 너무 느립니다.

댓글

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

나는이 답변을 정말 좋아합니다. 나중에 테스트 사례를 해결하려면 동일한 비율 확률을 병합하는 코드를 추가해야한다는 것을 알았습니다. 너무 느려서 놀랍지 않습니다
— Expired Data

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.