The series, 11 + 22 + 33 + ... + 1010 = 10405071317.
Find the last ten digits of the series, 11 + 22 + 33 + ... + 10001000.
In [1]:
def foo(n, m):
return str(sum(i ** i for i in range(1, n + 1)))[-m:]
In [2]:
foo(10, 10)
Out[2]:
In [3]:
n = 1000
m = 10
%timeit foo(n, m)
foo(n, m)
Out[3]:
I wonder if the third argument to pow() could help make the calculation faster by avoiding unnecessary calculations.
In [4]:
n = 1000
m = 10
%timeit n ** n
%timeit pow(n, n, 10**m)
In [5]:
def foo(n, m):
m10 = 10 ** m
return str(sum(pow(i, i, m10) for i in range(1, n + 1)))[-m:]
In [6]:
foo(10, 10)
Out[6]:
In [7]:
n = 1000
m = 10
%timeit foo(n, m)
foo(n, m)
Out[7]:
Try using modulo instead of str()[-m:] to get last m digits
In [8]:
def foo(n, m):
m10 = 10 ** m
return sum(pow(i, i, m10) for i in range(1, n + 1)) % m10
In [9]:
foo(10, 10)
Out[9]:
In [10]:
n = 1000
m = 10
%timeit foo(n, m)
foo(n, m)
Out[10]:
Cell #1 has the straightforward brute force approach. It is correct.
Cell #8 does not show leading zeroes, so it is not a good solution.
Cell #5 does show leading zeroes, has reasonable readability, and is fast.