mirror of
https://github.com/TheAlgorithms/Python.git
synced 2024-12-18 01:00:15 +00:00
Project Euler: 092 decreased the time (#6627)
* Added explanation and increased speed of the solution of problem 092 * updating DIRECTORY.md * Added temporary fix to the failing of problem 104 * Reduced few seconds by minor improvements * Update sol.py Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Co-authored-by: Christian Clauss <cclauss@me.com>
This commit is contained in:
parent
00dfad9d20
commit
84facb78b2
|
@ -11,11 +11,11 @@ What is most amazing is that EVERY starting number will eventually arrive at 1 o
|
||||||
How many starting numbers below ten million will arrive at 89?
|
How many starting numbers below ten million will arrive at 89?
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
DIGITS_SQUARED = [sum(int(c, 10) ** 2 for c in i.__str__()) for i in range(100000)]
|
||||||
DIGITS_SQUARED = [digit**2 for digit in range(10)]
|
|
||||||
|
|
||||||
|
|
||||||
def next_number(number: int) -> int:
|
def next_number(number: int) -> int:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Returns the next number of the chain by adding the square of each digit
|
Returns the next number of the chain by adding the square of each digit
|
||||||
to form a new number.
|
to form a new number.
|
||||||
|
@ -28,15 +28,29 @@ def next_number(number: int) -> int:
|
||||||
>>> next_number(32)
|
>>> next_number(32)
|
||||||
13
|
13
|
||||||
"""
|
"""
|
||||||
|
|
||||||
sum_of_digits_squared = 0
|
sum_of_digits_squared = 0
|
||||||
while number:
|
while number:
|
||||||
sum_of_digits_squared += DIGITS_SQUARED[number % 10]
|
|
||||||
number //= 10
|
# Increased Speed Slightly by checking every 5 digits together.
|
||||||
|
sum_of_digits_squared += DIGITS_SQUARED[number % 100000]
|
||||||
|
number //= 100000
|
||||||
|
|
||||||
return sum_of_digits_squared
|
return sum_of_digits_squared
|
||||||
|
|
||||||
|
|
||||||
CHAINS = {1: True, 58: False}
|
# There are 2 Chains made,
|
||||||
|
# One ends with 89 with the chain member 58 being the one which when declared first,
|
||||||
|
# there will be the least number of iterations for all the members to be checked.
|
||||||
|
|
||||||
|
# The other one ends with 1 and has only one element 1.
|
||||||
|
|
||||||
|
# So 58 and 1 are chosen to be declared at the starting.
|
||||||
|
|
||||||
|
# Changed dictionary to an array to quicken the solution
|
||||||
|
CHAINS: list[bool | None] = [None] * 10000000
|
||||||
|
CHAINS[0] = True
|
||||||
|
CHAINS[57] = False
|
||||||
|
|
||||||
|
|
||||||
def chain(number: int) -> bool:
|
def chain(number: int) -> bool:
|
||||||
|
@ -54,11 +68,16 @@ def chain(number: int) -> bool:
|
||||||
>>> chain(1)
|
>>> chain(1)
|
||||||
True
|
True
|
||||||
"""
|
"""
|
||||||
if number in CHAINS:
|
|
||||||
return CHAINS[number]
|
if CHAINS[number - 1] is not None:
|
||||||
|
return CHAINS[number - 1] # type: ignore
|
||||||
|
|
||||||
number_chain = chain(next_number(number))
|
number_chain = chain(next_number(number))
|
||||||
CHAINS[number] = number_chain
|
CHAINS[number - 1] = number_chain
|
||||||
|
|
||||||
|
while number < 10000000:
|
||||||
|
CHAINS[number - 1] = number_chain
|
||||||
|
number *= 10
|
||||||
|
|
||||||
return number_chain
|
return number_chain
|
||||||
|
|
||||||
|
@ -74,12 +93,15 @@ def solution(number: int = 10000000) -> int:
|
||||||
>>> solution(10000000)
|
>>> solution(10000000)
|
||||||
8581146
|
8581146
|
||||||
"""
|
"""
|
||||||
return sum(1 for i in range(1, number) if not chain(i))
|
for i in range(1, number):
|
||||||
|
if CHAINS[i] is None:
|
||||||
|
chain(i + 1)
|
||||||
|
|
||||||
|
return CHAINS[:number].count(False)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import doctest
|
import doctest
|
||||||
|
|
||||||
doctest.testmod()
|
doctest.testmod()
|
||||||
|
|
||||||
print(f"{solution() = }")
|
print(f"{solution() = }")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user