mirror of
https://github.com/TheAlgorithms/Python.git
synced 2025-01-31 06:33:44 +00:00
* Fixes: #3869: Optimize Project Euler's Problem 74's Solution 2 * updating DIRECTORY.md Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
This commit is contained in:
parent
2885a8cd99
commit
83b8b3c141
|
@ -16,9 +16,13 @@
|
||||||
the chains of non repeating items.
|
the chains of non repeating items.
|
||||||
The generation of the chain stops before a repeating item
|
The generation of the chain stops before a repeating item
|
||||||
or if the size of the chain is greater then the desired one.
|
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:
|
def factorial(a: int) -> int:
|
||||||
"""Returns the factorial of the input a
|
"""Returns the factorial of the input a
|
||||||
|
@ -36,18 +40,23 @@ def factorial(a: int) -> int:
|
||||||
if a < 0:
|
if a < 0:
|
||||||
raise ValueError("Invalid negative input!", a)
|
raise ValueError("Invalid negative input!", a)
|
||||||
|
|
||||||
|
if a in factorial_cache:
|
||||||
|
return factorial_cache[a]
|
||||||
|
|
||||||
# The case of 0! is handled separately
|
# The case of 0! is handled separately
|
||||||
if a == 0:
|
if a == 0:
|
||||||
return 1
|
factorial_cache[a] = 1
|
||||||
else:
|
else:
|
||||||
# use a temporary support variable to store the computation
|
# use a temporary support variable to store the computation
|
||||||
|
temporary_number = a
|
||||||
temporary_computation = 1
|
temporary_computation = 1
|
||||||
|
|
||||||
while a > 0:
|
while temporary_number > 0:
|
||||||
temporary_computation *= a
|
temporary_computation *= temporary_number
|
||||||
a -= 1
|
temporary_number -= 1
|
||||||
|
|
||||||
return temporary_computation
|
factorial_cache[a] = temporary_computation
|
||||||
|
return factorial_cache[a]
|
||||||
|
|
||||||
|
|
||||||
def factorial_sum(a: int) -> int:
|
def factorial_sum(a: int) -> int:
|
||||||
|
@ -57,7 +66,8 @@ def factorial_sum(a: int) -> int:
|
||||||
>>> factorial_sum(69)
|
>>> factorial_sum(69)
|
||||||
363600
|
363600
|
||||||
"""
|
"""
|
||||||
|
if a in factorial_sum_cache:
|
||||||
|
return factorial_sum_cache[a]
|
||||||
# Prepare a variable to hold the computation
|
# Prepare a variable to hold the computation
|
||||||
fact_sum = 0
|
fact_sum = 0
|
||||||
|
|
||||||
|
@ -67,17 +77,15 @@ def factorial_sum(a: int) -> int:
|
||||||
"""
|
"""
|
||||||
for i in str(a):
|
for i in str(a):
|
||||||
fact_sum += factorial(int(i))
|
fact_sum += factorial(int(i))
|
||||||
|
factorial_sum_cache[a] = fact_sum
|
||||||
return fact_sum
|
return fact_sum
|
||||||
|
|
||||||
|
|
||||||
def solution(chain_length: int = 60, number_limit: int = 1000000) -> int:
|
def solution(chain_length: int = 60, number_limit: int = 1000000) -> int:
|
||||||
"""Returns the number of numbers that produce
|
"""Returns the number of numbers that produce
|
||||||
chains with exactly 60 non repeating elements.
|
chains with exactly 60 non repeating elements.
|
||||||
>>> solution(60,1000000)
|
>>> solution(10, 1000)
|
||||||
402
|
26
|
||||||
>>> solution(15,1000000)
|
|
||||||
17800
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# the counter for the chains with the exact desired length
|
# 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):
|
for i in range(1, number_limit + 1):
|
||||||
|
|
||||||
# The temporary list will contain the elements of the chain
|
# 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
|
# The new element of the chain
|
||||||
new_chain_element = factorial_sum(chain_list[-1])
|
new_chain_element = factorial_sum(last_chain_element)
|
||||||
|
|
||||||
""" Stop computing the chain when you find a repeating item
|
# Stop computing the chain when you find a repeating item
|
||||||
or the length it greater then the desired one.
|
# 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])
|
while new_chain_element not in chain_set and len_chain_set <= chain_length:
|
||||||
|
chain_set.add(new_chain_element)
|
||||||
|
|
||||||
""" If the while exited because the chain list contains the exact amount of elements
|
len_chain_set += 1
|
||||||
increase the counter
|
last_chain_element = new_chain_element
|
||||||
"""
|
new_chain_element = factorial_sum(last_chain_element)
|
||||||
chain_counter += len(chain_list) == chain_length
|
|
||||||
|
# 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
|
return chain_counter
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user