Python/project_euler/problem_092/sol1.py
John Law 4bf2eedd3c
[mypy] fix mypy error in Project Euler Problem 092 solution 1 (#5357)
* fix mypy error

* updating DIRECTORY.md

* simplify code

* run black

* fix doc consistency

* Fix doc

* fix doc

Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
2021-10-17 08:07:45 +02:00

77 lines
2.1 KiB
Python

"""
Project Euler Problem 092: https://projecteuler.net/problem=92
Square digit chains
A number chain is created by continuously adding the square of the digits in
a number to form a new number until it has been seen before.
For example,
44 → 32 → 13 → 10 → 1 → 1
85 → 89 → 145 → 42 → 20 → 4 → 16 → 37 → 58 → 89
Therefore any chain that arrives at 1 or 89 will become stuck in an endless loop.
What is most amazing is that EVERY starting number will eventually arrive at 1 or 89.
How many starting numbers below ten million will arrive at 89?
"""
def next_number(number: int) -> int:
"""
Returns the next number of the chain by adding the square of each digit
to form a neww number.
For example if number = 12, next_number() will return 1^2 + 2^2 = 5.
Therefore, 5 is the next number of the chain.
>>> next_number(44)
32
>>> next_number(10)
1
>>> next_number(32)
13
"""
sum_of_digits_squared = 0
while number:
sum_of_digits_squared += (number % 10) ** 2
number //= 10
return sum_of_digits_squared
def chain(number: int) -> bool:
"""
The function generates the chain of numbers until the next number is 1 or 89.
For example, if starting number is 44, then the function generates the
following chain of numbers:
44 → 32 → 13 → 10 → 1 → 1.
Once the next number generated is 1 or 89, the function returns whether
or not the the next number generated by next_number() is 1.
>>> chain(10)
True
>>> chain(58)
False
>>> chain(1)
True
"""
while number != 1 and number != 89:
number = next_number(number)
return number == 1
def solution(number: int = 10000000) -> int:
"""
The function returns the number of integers that end up being 89 in each chain.
The function accepts a range number and the function checks all the values
under value number.
>>> solution(100)
80
>>> solution(10000000)
8581146
"""
return sum(1 for i in range(1, number) if not chain(i))
if __name__ == "__main__":
import doctest
doctest.testmod()
print(f"{solution() = }")