How to resolve the algorithm Iterated digits squaring step by step in the Python programming language
How to resolve the algorithm Iterated digits squaring step by step in the Python programming language
Table of Contents
Problem Statement
If you add the square of the digits of a Natural number (an integer bigger than zero), you always end with either 1 or 89: An example in Python:
Or, for much less credit - (showing that your algorithm and/or language is slow): This problem derives from the Project Euler problem 92. For a quick algorithm for this task see the talk page
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Iterated digits squaring step by step in the Python programming language
The code you provided consists of three different Python functions that calculate the number of D-digit numbers composed of digits from 0 through 9 that, when squared and summed, produce 89.
Main Function:
main()
:- It initializes a list
number
of 10 elements to store digits, a variableresult
to store the count of valid numbers, and a variablei
to traverse the list. - The outer loop iterates through the digits from right to left, with
i
representing the current digit's position. - If
i
is 0 and the current digit is 9, it indicates the end of the loop, and ifi
is the last index and the current digit is less than 9, it increments the digit and checks if the resulting number is valid. - If the current digit is 9, it moves to the previous digit by decrementing
i
. - Otherwise, it increments the current digit, copies its value to the remaining digits, updates
i
to the last index, and checks if the resulting number is valid. - The code accumulates the count of valid numbers in the
result
variable.
- It initializes a list
Helper Functions:
-
next_step(x)
:- This function squares and sums the digits of a number
x
to calculate the next step in the process of determining whether it produces 89 when squared and summed repeatedly.
- This function squares and sums the digits of a number
-
check(number)
:- It takes a list of digits
number
as input and checks if the corresponding number produces 89 when squared and summed repeatedly. - If the number produces 89, it calculates the number of unique permutations that can be formed from the digits in the number and returns that count. Otherwise, it returns 0.
- It takes a list of digits
Alternative Approaches (not in the provided code):
-
Using the
combinations_with_replacement
function from theitertools
module, you can generate all possible combinations of D digits and check if the corresponding number produces 89. -
Using the
@lru_cache
decorator, you can memoize the results of theids
function to optimize the computation. -
Using the
check89
function, you can iteratively check if a number produces 89 when squared and summed repeatedly.
These alternative approaches provide different ways to solve the same problem, emphasizing efficiency and optimization.
Source code in the python programming language
from math import ceil, log10, factorial
def next_step(x):
result = 0
while x > 0:
result += (x % 10) ** 2
x /= 10
return result
def check(number):
candidate = 0
for n in number:
candidate = candidate * 10 + n
while candidate != 89 and candidate != 1:
candidate = next_step(candidate)
if candidate == 89:
digits_count = [0] * 10
for d in number:
digits_count[d] += 1
result = factorial(len(number))
for c in digits_count:
result /= factorial(c)
return result
return 0
def main():
limit = 100000000
cache_size = int(ceil(log10(limit)))
assert 10 ** cache_size == limit
number = [0] * cache_size
result = 0
i = cache_size - 1
while True:
if i == 0 and number[i] == 9:
break
if i == cache_size - 1 and number[i] < 9:
number[i] += 1
result += check(number)
elif number[i] == 9:
i -= 1
else:
number[i] += 1
for j in xrange(i + 1, cache_size):
number[j] = number[i]
i = cache_size - 1
result += check(number)
print result
main()
from itertools import combinations_with_replacement
from array import array
from time import clock
D = 8
F = [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800, 87178291200, 1307674368000, 20922789888000, 355687428096000]
def b(n):
yield 1
for g in range(1,n+1):
gn = g
res = 0
while gn > 0:
gn,rem = divmod(gn,10)
res += rem**2
if res==89:
yield 0
else:
yield res
N = array('I',b(81*D))
for n in range(2,len(N)):
q = N[n]
while q>1:
q = N[q]
N[n] = q
es = clock()
z = 0
for n in combinations_with_replacement(range(10),D):
t = 0
for g in n:
t += g*g
if N[t] == 0:
continue
t = [0,0,0,0,0,0,0,0,0,0]
for g in n:
t[g] += 1
t1 = F[D]
for g in t:
t1 /= F[g]
z += t1
ee = clock() - es
print "\nD==" + str(D) + "\n " + str(z) + " numbers produce 1 and " + str(10**D-z) + " numbers produce 89"
print "Time ~= " + str(ee) + " secs"
>>> from functools import lru_cache
>>> @lru_cache(maxsize=1024)
def ids(n):
if n in {1, 89}: return n
else: return ids(sum(int(d) ** 2 for d in str(n)))
>>> ids(15)
89
>>> [ids(x) for x in range(1, 21)]
[1, 89, 89, 89, 89, 89, 1, 89, 89, 1, 89, 89, 1, 89, 89, 89, 89, 89, 1, 89]
>>> sum(ids(x) == 89 for x in range(1, 100000000))
85744333
>>>
>>> from functools import lru_cache
>>> @lru_cache(maxsize=1024)
def _ids(nt):
if nt in {('1',), ('8', '9')}: return nt
else: return _ids(tuple(sorted(str(sum(int(d) ** 2 for d in nt)))))
>>> def ids(n):
return int(''.join(_ids(tuple(sorted(str(n))))))
>>> ids(1), ids(15)
(1, 89)
>>> [ids(x) for x in range(1, 21)]
[1, 89, 89, 89, 89, 89, 1, 89, 89, 1, 89, 89, 1, 89, 89, 89, 89, 89, 1, 89]
>>> sum(ids(x) == 89 for x in range(1, 100000000))
85744333
>>> _ids.cache_info()
CacheInfo(hits=99991418, misses=5867462, maxsize=1024, currsize=1024)
>>>
from __future__ import print_function
from itertools import count
def check89(n):
while True:
n, t = 0, n
while t: n, t = n + (t%10)**2, t//10
if n <= 1: return False
if n ==89: return True
a, sq, is89 = [1], [x**2 for x in range(1, 10)], [False]
for n in range(1, 500):
b, a = a, a + [0]*81
is89 += map(check89, range(len(b), len(a)))
for i,v in enumerate(b):
for s in sq: a[i + s] += v
x = sum(a[i] for i in range(len(a)) if is89[i])
print("10^%d" % n, x)
You may also check:How to resolve the algorithm Loops/Infinite step by step in the EDSAC order code programming language
You may also check:How to resolve the algorithm P-Adic square roots step by step in the Julia programming language
You may also check:How to resolve the algorithm Look-and-say sequence step by step in the Objective-C programming language
You may also check:How to resolve the algorithm Command-line arguments step by step in the Sather programming language
You may also check:How to resolve the algorithm Input loop step by step in the BASIC programming language