|
| 1 | +""" |
| 2 | +A bag contains one red disc and one blue disc. In a game of chance a player takes a |
| 3 | +disc at random and its colour is noted. After each turn the disc is returned to the |
| 4 | +bag, an extra red disc is added, and another disc is taken at random. |
| 5 | +
|
| 6 | +The player pays £1 to play and wins if they have taken more blue discs than red |
| 7 | +discs at the end of the game. |
| 8 | +
|
| 9 | +If the game is played for four turns, the probability of a player winning is exactly |
| 10 | +11/120, and so the maximum prize fund the banker should allocate for winning in this |
| 11 | +game would be £10 before they would expect to incur a loss. Note that any payout will |
| 12 | +be a whole number of pounds and also includes the original £1 paid to play the game, |
| 13 | +so in the example given the player actually wins £9. |
| 14 | +
|
| 15 | +Find the maximum prize fund that should be allocated to a single game in which |
| 16 | +fifteen turns are played. |
| 17 | +
|
| 18 | +
|
| 19 | +Solution: |
| 20 | + For each 15-disc sequence of red and blue for which there are more red than blue, |
| 21 | + we calculate the probability of that sequence and add it to the total probability |
| 22 | + of the player winning. The inverse of this probability gives an upper bound for |
| 23 | + the prize if the banker wants to avoid an expected loss. |
| 24 | +""" |
| 25 | + |
| 26 | +from itertools import product |
| 27 | + |
| 28 | + |
| 29 | +def solution(num_turns: int = 15) -> int: |
| 30 | + """ |
| 31 | + Find the maximum prize fund that should be allocated to a single game in which |
| 32 | + fifteen turns are played. |
| 33 | + >>> solution(4) |
| 34 | + 10 |
| 35 | + >>> solution(10) |
| 36 | + 225 |
| 37 | + """ |
| 38 | + total_prob: float = 0.0 |
| 39 | + prob: float |
| 40 | + num_blue: int |
| 41 | + num_red: int |
| 42 | + ind: int |
| 43 | + col: int |
| 44 | + series: tuple[int, ...] |
| 45 | + |
| 46 | + for series in product(range(2), repeat=num_turns): |
| 47 | + num_blue = series.count(1) |
| 48 | + num_red = num_turns - num_blue |
| 49 | + if num_red >= num_blue: |
| 50 | + continue |
| 51 | + prob = 1.0 |
| 52 | + for ind, col in enumerate(series, 2): |
| 53 | + if col == 0: |
| 54 | + prob *= (ind - 1) / ind |
| 55 | + else: |
| 56 | + prob *= 1 / ind |
| 57 | + |
| 58 | + total_prob += prob |
| 59 | + |
| 60 | + return int(1 / total_prob) |
| 61 | + |
| 62 | + |
| 63 | +if __name__ == "__main__": |
| 64 | + print(f"{solution() = }") |
0 commit comments