From 53568cf4efd84f4b1c039eade335655842fa29e3 Mon Sep 17 00:00:00 2001 From: nico Date: Tue, 13 Oct 2020 00:21:04 +0200 Subject: [PATCH 01/11] add solution to Project Euler problem 206 --- project_euler/problem_206/__init__.py | 0 project_euler/problem_206/sol1.py | 30 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 project_euler/problem_206/__init__.py create mode 100644 project_euler/problem_206/sol1.py diff --git a/project_euler/problem_206/__init__.py b/project_euler/problem_206/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/project_euler/problem_206/sol1.py b/project_euler/problem_206/sol1.py new file mode 100644 index 000000000000..b2de1e499c01 --- /dev/null +++ b/project_euler/problem_206/sol1.py @@ -0,0 +1,30 @@ +""" +Problem Statement: +Find the unique positive integer whose square has the form 1_2_3_4_5_6_7_8_9_0, +where each “_” is a single digit. +""" + +from itertools import product + + +def solution() -> int: + """ + Returns the positive integer whose square has the form 1_2_3_4_5_6_7_8_9_0 using + itertool product to generate all possible digit combinations 0...9 for the nine "_" + to fill. + + >>> solution() + 1389019170 + """ + + for p in product("0123456789"[::-1], repeat=9): + squared = int("1{}2{}3{}4{}5{}6{}7{}8{}9{}0".format(*p)) + + root_integer = int(squared ** 0.5) + + if root_integer ** 2 == squared: + return root_integer + + +if __name__ == "__main__": + print(solution()) From 64e3d36cab2b68630b73a217c9ba455202d85cbb Mon Sep 17 00:00:00 2001 From: nico Date: Tue, 13 Oct 2020 19:53:50 +0200 Subject: [PATCH 02/11] Add solution to Project Euler problem 205 --- project_euler/problem_205/__init__.py | 0 project_euler/problem_205/sol1.py | 73 +++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 project_euler/problem_205/__init__.py create mode 100644 project_euler/problem_205/sol1.py diff --git a/project_euler/problem_205/__init__.py b/project_euler/problem_205/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/project_euler/problem_205/sol1.py b/project_euler/problem_205/sol1.py new file mode 100644 index 000000000000..fdd59c4c7ea3 --- /dev/null +++ b/project_euler/problem_205/sol1.py @@ -0,0 +1,73 @@ +""" +Project Euler problem 205: + + +Peter has nine four-sided (pyramidal) dice, each with faces numbered 1, 2, 3, 4. +Colin has six six-sided (cubic) dice, each with faces numbered 1, 2, 3, 4, 5, 6. + +Peter and Colin roll their dice and compare totals: the highest total wins. The result +is a draw if the totals are equal. + +What is the probability that Pyramidal Pete beats Cubic Colin? Give your answer rounded +to seven decimal places in the form 0.abcdefg +""" + +from itertools import product + + +def probability_of_sums( + dice_min: int = 1, dice_max: int = 6, dice_number: int = 6 +) -> (list, list): + """ + Returns the list of possible sums and their probabilities of dice_number dices with + numbers from dice_min to dice_max + """ + sums = [] + counter = [] + for dices in product(range(dice_min, dice_max + 1), repeat=dice_number): + s = sum(dices) + if s not in sums: + sums.append(s) + counter.append(1) + else: + idx = sums.index(s) + counter[idx] += 1 + total = sum(counter) + probability = [_t / total for _t in counter] + return sums, probability + + +def solution(): + """ + Returns the probability of Peter winning in dice game with nine four-sided + dice (1, 2, 3, 4 points) against Colin who has six six-sided dice (1, 2, 3, 4, 5, + 6). Winner of a match is who has more total points. + Algorithm calculates the possible point sums for each player and their + probabilities. Peter's probability to win is summed up from all the permutations + where he has more points than Colin. + + >>> solution() + 0.5731441 + """ + peter_wins = 0 + colin_wins = 0 + draw = 0 + for s_peter, p_peter in zip( + *probability_of_sums(dice_min=1, dice_max=4, dice_number=9) + ): + for s_colin, p_colin in zip( + *probability_of_sums(dice_min=1, dice_max=6, dice_number=6) + ): + p_branch = p_peter * p_colin + if s_peter > s_colin: + peter_wins += p_branch + elif s_colin > s_peter: + colin_wins += p_branch + else: + draw += p_branch + + return round(peter_wins, 7) + + +if __name__ == "__main__": + print(solution()) From 42d314221512bd38bdee500b7eed22e1f0ba4d92 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Sat, 17 Oct 2020 12:04:00 +0000 Subject: [PATCH 03/11] updating DIRECTORY.md --- DIRECTORY.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 72133a60b18a..77eef8ba3594 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -703,6 +703,10 @@ * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_174/sol1.py) * Problem 191 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_191/sol1.py) + * Problem 205 + * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_205/sol1.py) + * Problem 206 + * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_206/sol1.py) * Problem 234 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_234/sol1.py) * Problem 551 From 05853d81a1c59c0dd900b5a77fa9bceb5d439033 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Sat, 17 Oct 2020 15:27:52 +0000 Subject: [PATCH 04/11] updating DIRECTORY.md --- DIRECTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 77eef8ba3594..33eb6c97c500 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -48,6 +48,7 @@ * [Base32](https://github.com/TheAlgorithms/Python/blob/master/ciphers/base32.py) * [Base64 Cipher](https://github.com/TheAlgorithms/Python/blob/master/ciphers/base64_cipher.py) * [Base85](https://github.com/TheAlgorithms/Python/blob/master/ciphers/base85.py) + * [Beaufort Cipher](https://github.com/TheAlgorithms/Python/blob/master/ciphers/beaufort_cipher.py) * [Brute Force Caesar Cipher](https://github.com/TheAlgorithms/Python/blob/master/ciphers/brute_force_caesar_cipher.py) * [Caesar Cipher](https://github.com/TheAlgorithms/Python/blob/master/ciphers/caesar_cipher.py) * [Cryptomath Module](https://github.com/TheAlgorithms/Python/blob/master/ciphers/cryptomath_module.py) From c60eacd88ea7ea413d8ab87753136f833c99ab55 Mon Sep 17 00:00:00 2001 From: nico Date: Sun, 18 Oct 2020 22:14:12 +0200 Subject: [PATCH 05/11] Revert "Add solution to Project Euler problem 205" This reverts commit 64e3d36cab2b68630b73a217c9ba455202d85cbb. --- project_euler/problem_205/__init__.py | 0 project_euler/problem_205/sol1.py | 73 --------------------------- 2 files changed, 73 deletions(-) delete mode 100644 project_euler/problem_205/__init__.py delete mode 100644 project_euler/problem_205/sol1.py diff --git a/project_euler/problem_205/__init__.py b/project_euler/problem_205/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/project_euler/problem_205/sol1.py b/project_euler/problem_205/sol1.py deleted file mode 100644 index fdd59c4c7ea3..000000000000 --- a/project_euler/problem_205/sol1.py +++ /dev/null @@ -1,73 +0,0 @@ -""" -Project Euler problem 205: - - -Peter has nine four-sided (pyramidal) dice, each with faces numbered 1, 2, 3, 4. -Colin has six six-sided (cubic) dice, each with faces numbered 1, 2, 3, 4, 5, 6. - -Peter and Colin roll their dice and compare totals: the highest total wins. The result -is a draw if the totals are equal. - -What is the probability that Pyramidal Pete beats Cubic Colin? Give your answer rounded -to seven decimal places in the form 0.abcdefg -""" - -from itertools import product - - -def probability_of_sums( - dice_min: int = 1, dice_max: int = 6, dice_number: int = 6 -) -> (list, list): - """ - Returns the list of possible sums and their probabilities of dice_number dices with - numbers from dice_min to dice_max - """ - sums = [] - counter = [] - for dices in product(range(dice_min, dice_max + 1), repeat=dice_number): - s = sum(dices) - if s not in sums: - sums.append(s) - counter.append(1) - else: - idx = sums.index(s) - counter[idx] += 1 - total = sum(counter) - probability = [_t / total for _t in counter] - return sums, probability - - -def solution(): - """ - Returns the probability of Peter winning in dice game with nine four-sided - dice (1, 2, 3, 4 points) against Colin who has six six-sided dice (1, 2, 3, 4, 5, - 6). Winner of a match is who has more total points. - Algorithm calculates the possible point sums for each player and their - probabilities. Peter's probability to win is summed up from all the permutations - where he has more points than Colin. - - >>> solution() - 0.5731441 - """ - peter_wins = 0 - colin_wins = 0 - draw = 0 - for s_peter, p_peter in zip( - *probability_of_sums(dice_min=1, dice_max=4, dice_number=9) - ): - for s_colin, p_colin in zip( - *probability_of_sums(dice_min=1, dice_max=6, dice_number=6) - ): - p_branch = p_peter * p_colin - if s_peter > s_colin: - peter_wins += p_branch - elif s_colin > s_peter: - colin_wins += p_branch - else: - draw += p_branch - - return round(peter_wins, 7) - - -if __name__ == "__main__": - print(solution()) From 5f10606e67061eeed8d534401ed472604bf941af Mon Sep 17 00:00:00 2001 From: nico Date: Sun, 18 Oct 2020 22:14:28 +0200 Subject: [PATCH 06/11] Revert "add solution to Project Euler problem 206" This reverts commit 53568cf4efd84f4b1c039eade335655842fa29e3. --- project_euler/problem_206/__init__.py | 0 project_euler/problem_206/sol1.py | 30 --------------------------- 2 files changed, 30 deletions(-) delete mode 100644 project_euler/problem_206/__init__.py delete mode 100644 project_euler/problem_206/sol1.py diff --git a/project_euler/problem_206/__init__.py b/project_euler/problem_206/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/project_euler/problem_206/sol1.py b/project_euler/problem_206/sol1.py deleted file mode 100644 index b2de1e499c01..000000000000 --- a/project_euler/problem_206/sol1.py +++ /dev/null @@ -1,30 +0,0 @@ -""" -Problem Statement: -Find the unique positive integer whose square has the form 1_2_3_4_5_6_7_8_9_0, -where each “_” is a single digit. -""" - -from itertools import product - - -def solution() -> int: - """ - Returns the positive integer whose square has the form 1_2_3_4_5_6_7_8_9_0 using - itertool product to generate all possible digit combinations 0...9 for the nine "_" - to fill. - - >>> solution() - 1389019170 - """ - - for p in product("0123456789"[::-1], repeat=9): - squared = int("1{}2{}3{}4{}5{}6{}7{}8{}9{}0".format(*p)) - - root_integer = int(squared ** 0.5) - - if root_integer ** 2 == squared: - return root_integer - - -if __name__ == "__main__": - print(solution()) From 7ae0d6f47e407dc7b549ce2c3ee74f5c1b310afb Mon Sep 17 00:00:00 2001 From: nico Date: Mon, 19 Oct 2020 00:01:25 +0200 Subject: [PATCH 07/11] add solution for project euler problem 207 --- project_euler/problem_207/__init__.py | 0 project_euler/problem_207/sol1.py | 96 +++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 project_euler/problem_207/__init__.py create mode 100644 project_euler/problem_207/sol1.py diff --git a/project_euler/problem_207/__init__.py b/project_euler/problem_207/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/project_euler/problem_207/sol1.py b/project_euler/problem_207/sol1.py new file mode 100644 index 000000000000..8d238f4a4ac3 --- /dev/null +++ b/project_euler/problem_207/sol1.py @@ -0,0 +1,96 @@ +""" + +Project Euler Problem 207: https://projecteuler.net/problem=207 + +Problem Statement: +For some positive integers k, there exists an integer partition of the form +4**t = 2**t + k, where 4**t, 2**t, and k are all positive integers and t is a real +number. The first two such partitions are 4**1 = 2**1 + 2 and +4**1.5849625... = 2**1.5849625... + 6. +Partitions where t is also an integer are called perfect. +For any m ≥ 1 let P(m) be the proportion of such partitions that are perfect with +k ≤ m. +Thus P(6) = 1/2. +In the following table are listed some values of P(m) + + P(5) = 1/1 + P(10) = 1/2 + P(15) = 2/3 + P(20) = 1/2 + P(25) = 1/2 + P(30) = 2/5 + ... + P(180) = 1/4 + P(185) = 3/13 + +Find the smallest m for which P(m) < 1/12345 + +Solution: +Equation 4**t = 2**t + k solved for t gives: + t = log2(sqrt(4*k+1)/2 + 1/2) +For t to be real valued, sqrt(4*k+1) must be an integer which is implemented in +function check_t_real(k). For a perfect partition t must be an integer. +To speed up significantly the search for partitions, instead of incrementing k by one +per iteration, the next valid k is found by k = (i**2 - 1) / 4 with an integer i and +k has to be a positive integer. If this is the case a partition is found. The partition +is perfect if t os an integer. The integer i is increased with increment 1 until the +proportion perfect partitions / total partitions drops under the given value. + +""" + +import math + + +def check_partition_perfect(k): + """ + + Check if t = f(k) = log2(sqrt(4*k+1)/2 + 1/2) is a real number. + + >>> check_partition_perfect(2) + True + + >>> check_partition_perfect(6) + False + + """ + + t = math.log2(math.sqrt(4 * k + 1) / 2 + 1 / 2) + + return t == int(t) + + +def solution(max_proportion: float = 1 / 12456) -> int: + """ + Find m for which the proportion of perfect partitions to total partitions is lower + than max_proportion + + >>> solution(1) > 5 + True + + >>> solution(3 / 13) > 185 + True + + >>> solution(1 / 12345) + 44043947822 + + """ + + total = 0 + perfect = 0 + + i = 3 + while True: + k = (i ** 2 - 1) / 4 + if k == int(k): # if k = f(i) is an integer, then there is a partition for k + k = int(k) + total += 1 + if check_partition_perfect(k): + perfect += 1 + if perfect > 0: + if perfect / total < max_proportion: + return k + i += 1 + + +if __name__ == "__main__": + print(f"{solution() = }") From e916ab02c121c54dec04237ded07e51d871a66fc Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Sun, 18 Oct 2020 22:02:34 +0000 Subject: [PATCH 08/11] updating DIRECTORY.md --- DIRECTORY.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/DIRECTORY.md b/DIRECTORY.md index 07df69ba9ddd..bd636a174909 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -705,10 +705,8 @@ * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_174/sol1.py) * Problem 191 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_191/sol1.py) - * Problem 205 - * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_205/sol1.py) - * Problem 206 - * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_206/sol1.py) + * Problem 207 + * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_207/sol1.py) * Problem 234 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_234/sol1.py) * Problem 551 From 4fb4a1ced4537472830f1ffb2082c6cd58d8fdb7 Mon Sep 17 00:00:00 2001 From: nico Date: Mon, 19 Oct 2020 00:05:00 +0200 Subject: [PATCH 09/11] add type hint for output of helper function --- project_euler/problem_207/sol1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project_euler/problem_207/sol1.py b/project_euler/problem_207/sol1.py index 8d238f4a4ac3..cfaa182a8063 100644 --- a/project_euler/problem_207/sol1.py +++ b/project_euler/problem_207/sol1.py @@ -41,7 +41,7 @@ import math -def check_partition_perfect(k): +def check_partition_perfect(k) -> bool: """ Check if t = f(k) = log2(sqrt(4*k+1)/2 + 1/2) is a real number. From 4a842ee2522718ae013a03e73e2e82b96b329238 Mon Sep 17 00:00:00 2001 From: PetitNigaud <44503597+PetitNigaud@users.noreply.github.com> Date: Mon, 19 Oct 2020 10:18:15 +0200 Subject: [PATCH 10/11] Correct default parameter value in solution --- project_euler/problem_207/sol1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project_euler/problem_207/sol1.py b/project_euler/problem_207/sol1.py index cfaa182a8063..ce89b1980ccf 100644 --- a/project_euler/problem_207/sol1.py +++ b/project_euler/problem_207/sol1.py @@ -59,7 +59,7 @@ def check_partition_perfect(k) -> bool: return t == int(t) -def solution(max_proportion: float = 1 / 12456) -> int: +def solution(max_proportion: float = 1 / 12345) -> int: """ Find m for which the proportion of perfect partitions to total partitions is lower than max_proportion From fce5a5cc4885a998cfa5796a9ee93069bf632300 Mon Sep 17 00:00:00 2001 From: nico Date: Wed, 21 Oct 2020 21:59:46 +0200 Subject: [PATCH 11/11] use descriptive variable names and remove problem solution from doctest Fixes: #2695 --- project_euler/problem_207/sol1.py | 42 ++++++++++++++++--------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/project_euler/problem_207/sol1.py b/project_euler/problem_207/sol1.py index cfaa182a8063..fbd6ce285c5a 100644 --- a/project_euler/problem_207/sol1.py +++ b/project_euler/problem_207/sol1.py @@ -41,10 +41,11 @@ import math -def check_partition_perfect(k) -> bool: +def check_partition_perfect(positive_integer: int) -> bool: """ - Check if t = f(k) = log2(sqrt(4*k+1)/2 + 1/2) is a real number. + Check if t = f(positive_integer) = log2(sqrt(4*positive_integer+1)/2 + 1/2) is a + real number. >>> check_partition_perfect(2) True @@ -54,9 +55,9 @@ def check_partition_perfect(k) -> bool: """ - t = math.log2(math.sqrt(4 * k + 1) / 2 + 1 / 2) + exponent = math.log2(math.sqrt(4 * positive_integer + 1) / 2 + 1 / 2) - return t == int(t) + return exponent == int(exponent) def solution(max_proportion: float = 1 / 12456) -> int: @@ -67,29 +68,30 @@ def solution(max_proportion: float = 1 / 12456) -> int: >>> solution(1) > 5 True - >>> solution(3 / 13) > 185 + >>> solution(1/2) > 10 True - >>> solution(1 / 12345) - 44043947822 + >>> solution(3 / 13) > 185 + True """ - total = 0 - perfect = 0 + total_partitions = 0 + perfect_partitions = 0 - i = 3 + integer = 3 while True: - k = (i ** 2 - 1) / 4 - if k == int(k): # if k = f(i) is an integer, then there is a partition for k - k = int(k) - total += 1 - if check_partition_perfect(k): - perfect += 1 - if perfect > 0: - if perfect / total < max_proportion: - return k - i += 1 + partition_candidate = (integer ** 2 - 1) / 4 + # if candidate is an integer, then there is a partition for k + if partition_candidate == int(partition_candidate): + partition_candidate = int(partition_candidate) + total_partitions += 1 + if check_partition_perfect(partition_candidate): + perfect_partitions += 1 + if perfect_partitions > 0: + if perfect_partitions / total_partitions < max_proportion: + return partition_candidate + integer += 1 if __name__ == "__main__":