Skip to content

Commit 806734c

Browse files
committed
Added solution for Project Euler problem 121
1 parent ecf9b81 commit 806734c

File tree

2 files changed

+65
-0
lines changed

2 files changed

+65
-0
lines changed

project_euler/problem_121/__init__.py

Whitespace-only changes.

project_euler/problem_121/sol1.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
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+
from typing import Tuple
28+
29+
30+
def solution(num_turns: int = 15) -> int:
31+
"""
32+
Find the maximum prize fund that should be allocated to a single game in which
33+
fifteen turns are played.
34+
>>> solution(4)
35+
10
36+
>>> solution(10)
37+
225
38+
"""
39+
total_prob: float = 0.0
40+
prob: float
41+
num_blue: int
42+
num_red: int
43+
ind: int
44+
col: int
45+
series: Tuple[int, ...]
46+
47+
for series in product(range(2), repeat=num_turns):
48+
num_blue = series.count(1)
49+
num_red = num_turns - num_blue
50+
if num_red >= num_blue:
51+
continue
52+
prob = 1.0
53+
for ind, col in enumerate(series, 2):
54+
if col == 0:
55+
prob *= (ind - 1) / ind
56+
else:
57+
prob *= 1 / ind
58+
59+
total_prob += prob
60+
61+
return int(1 / total_prob)
62+
63+
64+
if __name__ == "__main__":
65+
print(f"{solution() = }")

0 commit comments

Comments
 (0)