Skip to content

Added solution for Project Euler problem 109 #4080

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
* [Binary Count Setbits](https://github.com/TheAlgorithms/Python/blob/master/bit_manipulation/binary_count_setbits.py)
* [Binary Count Trailing Zeros](https://github.com/TheAlgorithms/Python/blob/master/bit_manipulation/binary_count_trailing_zeros.py)
* [Binary Or Operator](https://github.com/TheAlgorithms/Python/blob/master/bit_manipulation/binary_or_operator.py)
* [Binary Shifts](https://github.com/TheAlgorithms/Python/blob/master/bit_manipulation/binary_shifts.py)
* [Binary Twos Complement](https://github.com/TheAlgorithms/Python/blob/master/bit_manipulation/binary_twos_complement.py)
* [Binary Xor Operator](https://github.com/TheAlgorithms/Python/blob/master/bit_manipulation/binary_xor_operator.py)
* [Count Number Of One Bits](https://github.com/TheAlgorithms/Python/blob/master/bit_manipulation/count_number_of_one_bits.py)
* [Reverse Bits](https://github.com/TheAlgorithms/Python/blob/master/bit_manipulation/reverse_bits.py)
Expand Down Expand Up @@ -278,6 +280,7 @@
## Graphics
* [Bezier Curve](https://github.com/TheAlgorithms/Python/blob/master/graphics/bezier_curve.py)
* [Koch Snowflake](https://github.com/TheAlgorithms/Python/blob/master/graphics/koch_snowflake.py)
* [Mandelbrot](https://github.com/TheAlgorithms/Python/blob/master/graphics/mandelbrot.py)
* [Vector3 For 2D Rendering](https://github.com/TheAlgorithms/Python/blob/master/graphics/vector3_for_2d_rendering.py)

## Graphs
Expand Down Expand Up @@ -469,6 +472,7 @@
* [Runge Kutta](https://github.com/TheAlgorithms/Python/blob/master/maths/runge_kutta.py)
* [Segmented Sieve](https://github.com/TheAlgorithms/Python/blob/master/maths/segmented_sieve.py)
* Series
* [Geometric Mean](https://github.com/TheAlgorithms/Python/blob/master/maths/series/geometric_mean.py)
* [Geometric Series](https://github.com/TheAlgorithms/Python/blob/master/maths/series/geometric_series.py)
* [Harmonic Series](https://github.com/TheAlgorithms/Python/blob/master/maths/series/harmonic_series.py)
* [P Series](https://github.com/TheAlgorithms/Python/blob/master/maths/series/p_series.py)
Expand Down Expand Up @@ -757,6 +761,8 @@
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_102/sol1.py)
* Problem 107
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_107/sol1.py)
* Problem 109
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_109/sol1.py)
* Problem 112
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_112/sol1.py)
* Problem 113
Expand Down
Empty file.
89 changes: 89 additions & 0 deletions project_euler/problem_109/sol1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
"""
In the game of darts a player throws three darts at a target board which is
split into twenty equal sized sections numbered one to twenty.
The score of a dart is determined by the number of the region that the dart
lands in. A dart landing outside the red/green outer ring scores zero. The black
and cream regions inside this ring represent single scores. However, the red/green
outer ring and middle ring score double and treble scores respectively.

At the centre of the board are two concentric circles called the bull region, or
bulls-eye. The outer bull is worth 25 points and the inner bull is a double,
worth 50 points.

There are many variations of rules but in the most popular game the players will
begin with a score 301 or 501 and the first player to reduce their running total
to zero is a winner. However, it is normal to play a "doubles out" system, which
means that the player must land a double (including the double bulls-eye at the
centre of the board) on their final dart to win; any other dart that would reduce
their running total to one or lower means the score for that set of three darts
is "bust".

When a player is able to finish on their current score it is called a "checkout"
and the highest checkout is 170: T20 T20 D25 (two treble 20s and double bull).

There are exactly eleven distinct ways to checkout on a score of 6:

D3
D1 D2
S2 D2
D2 D1
S4 D1
S1 S1 D2
S1 T1 D1
S1 S3 D1
D1 D1 D1
D1 S2 D1
S2 S2 D1

Note that D1 D2 is considered different to D2 D1 as they finish on different
doubles. However, the combination S1 T1 D1 is considered the same as T1 S1 D1.

In addition we shall not include misses in considering combinations; for example,
D3 is the same as 0 D3 and 0 0 D3.

Incredibly there are 42336 distinct ways of checking out in total.

How many distinct ways can a player checkout with a score less than 100?

Solution:
We first construct a list of the possible dart values, separated by type.
We then iterate through the doubles, followed by the possible 2 following throws.
If the total of these three darts is less than the given limit, we increment
the counter.
"""

from itertools import combinations_with_replacement


def solution(limit: int = 100) -> int:
"""
Count the number of distinct ways a player can checkout with a score
less than limit.
>>> solution(171)
42336
>>> solution(50)
12577
"""
singles: list[int] = [x for x in range(1, 21)] + [25]
doubles: list[int] = [2 * x for x in range(1, 21)] + [50]
triples: list[int] = [3 * x for x in range(1, 21)]
all_values: list[int] = singles + doubles + triples + [0]

num_checkouts: int = 0
double: int
throw1: int
throw2: int
checkout_total: int

for double in doubles:
for throw1, throw2 in combinations_with_replacement(all_values, 2):
checkout_total = double + throw1 + throw2
if checkout_total < limit:
num_checkouts += 1

return num_checkouts


if __name__ == "__main__":
print(f"{solution() = }")