From 89a43c81e50e0b5b46da78143a239967e198c1fa Mon Sep 17 00:00:00 2001 From: fpringle Date: Sat, 20 Mar 2021 06:59:48 +0100 Subject: [PATCH] feat: Add solution for Project Euler Problem 121 (#4261) * Added solution for Project Euler problem 121 * Updated typing for 3.9 * updating DIRECTORY.md Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> --- DIRECTORY.md | 2 + project_euler/problem_121/__init__.py | 0 project_euler/problem_121/sol1.py | 64 +++++++++++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 project_euler/problem_121/__init__.py create mode 100644 project_euler/problem_121/sol1.py diff --git a/DIRECTORY.md b/DIRECTORY.md index 136825e41..070119f2f 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -772,6 +772,8 @@ * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_119/sol1.py) * Problem 120 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_120/sol1.py) + * Problem 121 + * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_121/sol1.py) * Problem 123 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_123/sol1.py) * Problem 125 diff --git a/project_euler/problem_121/__init__.py b/project_euler/problem_121/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/project_euler/problem_121/sol1.py b/project_euler/problem_121/sol1.py new file mode 100644 index 000000000..93679cf4a --- /dev/null +++ b/project_euler/problem_121/sol1.py @@ -0,0 +1,64 @@ +""" +A bag contains one red disc and one blue disc. In a game of chance a player takes a +disc at random and its colour is noted. After each turn the disc is returned to the +bag, an extra red disc is added, and another disc is taken at random. + +The player pays £1 to play and wins if they have taken more blue discs than red +discs at the end of the game. + +If the game is played for four turns, the probability of a player winning is exactly +11/120, and so the maximum prize fund the banker should allocate for winning in this +game would be £10 before they would expect to incur a loss. Note that any payout will +be a whole number of pounds and also includes the original £1 paid to play the game, +so in the example given the player actually wins £9. + +Find the maximum prize fund that should be allocated to a single game in which +fifteen turns are played. + + +Solution: + For each 15-disc sequence of red and blue for which there are more red than blue, + we calculate the probability of that sequence and add it to the total probability + of the player winning. The inverse of this probability gives an upper bound for + the prize if the banker wants to avoid an expected loss. +""" + +from itertools import product + + +def solution(num_turns: int = 15) -> int: + """ + Find the maximum prize fund that should be allocated to a single game in which + fifteen turns are played. + >>> solution(4) + 10 + >>> solution(10) + 225 + """ + total_prob: float = 0.0 + prob: float + num_blue: int + num_red: int + ind: int + col: int + series: tuple[int, ...] + + for series in product(range(2), repeat=num_turns): + num_blue = series.count(1) + num_red = num_turns - num_blue + if num_red >= num_blue: + continue + prob = 1.0 + for ind, col in enumerate(series, 2): + if col == 0: + prob *= (ind - 1) / ind + else: + prob *= 1 / ind + + total_prob += prob + + return int(1 / total_prob) + + +if __name__ == "__main__": + print(f"{solution() = }")