From d827fde1b455640957411cc3c4457bb97f250db9 Mon Sep 17 00:00:00 2001 From: vasu Date: Thu, 19 Nov 2020 19:19:37 +0000 Subject: [PATCH 1/2] Fixes: #3869: Optimize Project Euler's Problem 74's Solution 2 --- project_euler/problem_074/sol2.py | 68 ++++++++++++++++++------------- 1 file changed, 39 insertions(+), 29 deletions(-) diff --git a/project_euler/problem_074/sol2.py b/project_euler/problem_074/sol2.py index 0348ef1a6628..689593277a81 100644 --- a/project_euler/problem_074/sol2.py +++ b/project_euler/problem_074/sol2.py @@ -16,9 +16,13 @@ the chains of non repeating items. The generation of the chain stops before a repeating item or if the size of the chain is greater then the desired one. - After generating each chain, the length is checked and the counter increases. + After generating each chain, the length is checked and the + counter increases. """ +factorial_cache = {} +factorial_sum_cache = {} + def factorial(a: int) -> int: """Returns the factorial of the input a @@ -36,18 +40,23 @@ def factorial(a: int) -> int: if a < 0: raise ValueError("Invalid negative input!", a) + if a in factorial_cache: + return factorial_cache[a] + # The case of 0! is handled separately if a == 0: - return 1 + factorial_cache[a] = 1 else: # use a temporary support variable to store the computation + temporary_number = a temporary_computation = 1 - while a > 0: - temporary_computation *= a - a -= 1 + while temporary_number > 0: + temporary_computation *= temporary_number + temporary_number -= 1 - return temporary_computation + factorial_cache[a] = temporary_computation + return factorial_cache[a] def factorial_sum(a: int) -> int: @@ -57,7 +66,8 @@ def factorial_sum(a: int) -> int: >>> factorial_sum(69) 363600 """ - + if a in factorial_sum_cache: + return factorial_sum_cache[a] # Prepare a variable to hold the computation fact_sum = 0 @@ -67,17 +77,15 @@ def factorial_sum(a: int) -> int: """ for i in str(a): fact_sum += factorial(int(i)) - + factorial_sum_cache[a] = fact_sum return fact_sum def solution(chain_length: int = 60, number_limit: int = 1000000) -> int: """Returns the number of numbers that produce chains with exactly 60 non repeating elements. - >>> solution(60,1000000) - 402 - >>> solution(15,1000000) - 17800 + >>> solution(10, 1000) + 26 """ # the counter for the chains with the exact desired length @@ -86,25 +94,27 @@ def solution(chain_length: int = 60, number_limit: int = 1000000) -> int: for i in range(1, number_limit + 1): # The temporary list will contain the elements of the chain - chain_list = [i] + chain_set = {i} + len_chain_set = 1 + last_chain_element = i # The new element of the chain - new_chain_element = factorial_sum(chain_list[-1]) - - """ Stop computing the chain when you find a repeating item - or the length it greater then the desired one. - """ - while not (new_chain_element in chain_list) and ( - len(chain_list) <= chain_length - ): - chain_list += [new_chain_element] - - new_chain_element = factorial_sum(chain_list[-1]) - - """ If the while exited because the chain list contains the exact amount of elements - increase the counter - """ - chain_counter += len(chain_list) == chain_length + new_chain_element = factorial_sum(last_chain_element) + + # Stop computing the chain when you find a repeating item + # or the length it greater then the desired one. + + while new_chain_element not in chain_set and len_chain_set <= chain_length: + chain_set.add(new_chain_element) + + len_chain_set += 1 + last_chain_element = new_chain_element + new_chain_element = factorial_sum(last_chain_element) + + # If the while exited because the chain list contains the exact amount + # of elements increase the counter + if len_chain_set == chain_length: + chain_counter += 1 return chain_counter From d8400db59419a6b187f6b1ec82a546751f559cfa Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Thu, 19 Nov 2020 19:20:29 +0000 Subject: [PATCH 2/2] updating DIRECTORY.md --- DIRECTORY.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 0cecae28d51d..afae5fa17542 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -205,6 +205,7 @@ * [Heaps Algorithm](https://github.com/TheAlgorithms/Python/blob/master/divide_and_conquer/heaps_algorithm.py) * [Heaps Algorithm Iterative](https://github.com/TheAlgorithms/Python/blob/master/divide_and_conquer/heaps_algorithm_iterative.py) * [Inversions](https://github.com/TheAlgorithms/Python/blob/master/divide_and_conquer/inversions.py) + * [Kth Order Statistic](https://github.com/TheAlgorithms/Python/blob/master/divide_and_conquer/kth_order_statistic.py) * [Max Subarray Sum](https://github.com/TheAlgorithms/Python/blob/master/divide_and_conquer/max_subarray_sum.py) * [Mergesort](https://github.com/TheAlgorithms/Python/blob/master/divide_and_conquer/mergesort.py) * [Power](https://github.com/TheAlgorithms/Python/blob/master/divide_and_conquer/power.py) @@ -389,6 +390,7 @@ * [Chudnovsky Algorithm](https://github.com/TheAlgorithms/Python/blob/master/maths/chudnovsky_algorithm.py) * [Collatz Sequence](https://github.com/TheAlgorithms/Python/blob/master/maths/collatz_sequence.py) * [Combinations](https://github.com/TheAlgorithms/Python/blob/master/maths/combinations.py) + * [Decimal Isolate](https://github.com/TheAlgorithms/Python/blob/master/maths/decimal_isolate.py) * [Entropy](https://github.com/TheAlgorithms/Python/blob/master/maths/entropy.py) * [Eulers Totient](https://github.com/TheAlgorithms/Python/blob/master/maths/eulers_totient.py) * [Explicit Euler](https://github.com/TheAlgorithms/Python/blob/master/maths/explicit_euler.py) @@ -492,6 +494,7 @@ * [Autocomplete Using Trie](https://github.com/TheAlgorithms/Python/blob/master/other/autocomplete_using_trie.py) * [Binary Exponentiation](https://github.com/TheAlgorithms/Python/blob/master/other/binary_exponentiation.py) * [Binary Exponentiation 2](https://github.com/TheAlgorithms/Python/blob/master/other/binary_exponentiation_2.py) + * [Davis–Putnam–Logemann–Loveland](https://github.com/TheAlgorithms/Python/blob/master/other/davis–putnam–logemann–loveland.py) * [Detecting English Programmatically](https://github.com/TheAlgorithms/Python/blob/master/other/detecting_english_programmatically.py) * [Dijkstra Bankers Algorithm](https://github.com/TheAlgorithms/Python/blob/master/other/dijkstra_bankers_algorithm.py) * [Doomsday](https://github.com/TheAlgorithms/Python/blob/master/other/doomsday.py) @@ -659,6 +662,8 @@ * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_048/sol1.py) * Problem 049 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_049/sol1.py) + * Problem 050 + * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_050/sol1.py) * Problem 051 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_051/sol1.py) * Problem 052 @@ -680,6 +685,8 @@ * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_062/sol1.py) * Problem 063 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_063/sol1.py) + * Problem 064 + * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_064/sol1.py) * Problem 065 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_065/sol1.py) * Problem 067 @@ -693,6 +700,7 @@ * [Sol2](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_072/sol2.py) * Problem 074 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_074/sol1.py) + * [Sol2](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_074/sol2.py) * Problem 075 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_075/sol1.py) * Problem 076 @@ -717,6 +725,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 123 + * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_123/sol1.py) * Problem 125 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_125/sol1.py) * Problem 173 @@ -725,12 +735,16 @@ * [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 203 + * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_203/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 301 + * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_301/sol1.py) * Problem 551 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_551/sol1.py)