If you say you get a 'time limit exceeded' message it would be interesting how large the string and the prime number and the time limit is. It seems that the prime is about \$10^9\$ , the string length is about \$10^6\$ and the time limit is about 2 seconds. You should use a profiler to find out where you spent the time in your program. I did this for a string of length \$10^4\$ . The program took about 11 seconds on my notebook and almost all of the time is spent for the calculation of res
. The loop is executed \$10^4\$ times, so each calculation took about 1 ms. What is done during this millisecond? From the string of length \$10^4\$ a substring most of the time of length \$10^4\$ is taken and converted to an integer. This \$10^4\$ digit integer is divided by p to get the residue.
Can the performance of such a step be improved by using the results of a previous step?
Yes, I think so. The new substring differs from the old substring only by one character.
So you have to convert only this one character to integer. The new residuum can be calculated now based on this number and the previously calculated values like the previous residue.
If you need the powers of \$10^i\$ in your calculation modulo p you should keep them reduced modulo p, otherwise they will become rather big (\$10^6\$ digit integers)
So the following is bad because you calculate with 1000000-digit numbers
p= some prime number of size (not length) 10**9
power=1
for _ in range(10**6):
power=10*power
result=power % p
This one is much much better:
p= some prime number of size (not length) 10**9
power=1
for _ in range(10**6):
power=(10*power)%p
result=power % p
because you calculate with 9-digit numbers
you can always measure the time your code needs with time.time
import time
starttime=time.time()
my code
endtime=time.time()
print(endtime-starttime)
You will see the difference in the previous examples with the loops.
To testthe performance of the code one needs a 9-digit prime number and a \$10^6\$ digit string.
p=623456849
random.seed(12345678)
number=''.join(random.choices(string.digits, k=10**6))
The random.seed
command guarantees that always the sam string is generated. The prime number p is from the internet. But for p one can use an arbitrary number that is not divisible by 2 or 5.