2

I made a program that will return value of selected index and 5 next index next to it of a string "number". since the string is really big, most of computer are taking too long to do the work. i need to optimize the code. I read somewhere that lamda function can help me. can here someone please suggest me other ways of making the string or other way of making the program.

number = ""
for num in range(2,999999):
    prime = True
    for i in range(2,num):
        if (num%i==0):
            prime = False
    if prime:
        number = number + str(num)              
print(number[n:n+5])

PS = I made this and this one is surely more optomised

def answer(n):
 number = "2357"
 i = 9
 while(i<999999):
  prime = True
  if (i%5==0):
   i=i+2             
   prime = False
   continue   
  if (i%3==0 | i%7==0):
   i=i+2                 
   prime = False
   continue
  if prime:
   number = number + str(i) 
   i=i+2
   continue                      
 print(number[n:n+5])                                             

3 Answers3

0

Below code is more optimized

number = ""
for num in range(2,999999):
    prime = True
    for i in range(2,num/2):
        if (num%i==0):
            prime = False
            break
    if prime:
        number = number + str(num)              
print(number[n:n+5])

1) Once you find number is not prime, you should break the loop instead of continuing the loop. 2) There is no need to go upto n-1 to check whether it is prime or not. you can check it by just going upto n/2

Jay Parikh
  • 2,133
  • 14
  • 13
0

lambda won't help you but your code could be a little optimised

import math
number = ""
for num in range(2,999999):
   prime = True
   for i in range(2, int(math.sqrt(num))):
       if (num%i==0):
           prime = False
           break
   if prime:
       number = number + str(num)              
print(number[n:n+5])
vZ10
  • 1,988
  • 1
  • 19
  • 30
0

There are many faster prime generating algorithms, see for example:

The code example below uses the Sieve of Eratosthenes found in an answer of Eli Bendersky

Strings are immutable objects in Python, thus string concatenation using the plus operator is not very efficient especially for long strings, I assume a run time behavior of O(n2). A comparison of string concatenation methods can be found in Efficient String Concatenation in Python.

The following code uses join with a generator. Also, it is not necessary to calculate the whole string beyond n + 5.

Links for understanding generators:

Code:

import math

# Sieve of Eratosthenes
# Code by David Eppstein, UC Irvine, 28 Feb 2002
# http://code.activestate.com/recipes/117119/

def gen_primes():
    """ Generate an infinite sequence of prime numbers.
    """
    # Maps composites to primes witnessing their compositeness.
    # This is memory efficient, as the sieve is not "run forward"
    # indefinitely, but only as long as required by the current
    # number being tested.
    #
    D = {}

    # The running integer that's checked for primeness
    q = 2

    while True:
        if q not in D:
            # q is a new prime.
            # Yield it and mark its first multiple that isn't
            # already marked in previous iterations
            #
            yield q
            D[q * q] = [q]
        else:
            # q is composite. D[q] is the list of primes that
            # divide it. Since we've reached q, we no longer
            # need it in the map, but we'll mark the next
            # multiples of its witnesses to prepare for larger
            # numbers
            #
            for p in D[q]:
                D.setdefault(p + q, []).append(p)
            del D[q]

        q += 1


def gen_primes_limited_by_total_length(length):
    total = 0
    for prime in gen_primes():
        yield prime
        total += len(str(prime))
        if total > length:
            return

def my_func(n):
    return ''.join(
        str(prime)
        for prime in gen_primes_limited_by_total_length(n + 5)
    )[n:n + 5]


print(my_func(0))
print(my_func(10))
print(my_func(10000))
print(my_func(1234567))

Result:

23571
19232
02192
81258

I do not know, how often, my_func would be used. Thus, an alternative is to calculate the whole string in memory. But, the string generation can be a waste of time, if it is done for large number of primes, but only small values for n are used.

A small optimization of my_func would be to limit the string length by not using the primes that are too small for n. It saves memory, but the run-time is not much affected, because the generation of the primes cost most of the time.

def my_func(n):
    total = 0
    s = ''
    for prime in gen_primes():
        p = str(prime)
        lp = len(p)
        if lp <= n:
            n -= lp
        elif n > 0:
            s = p[n:]
            n = 0
        else:
            s += p
            ls = len(s)
            if ls >= 5:
                return s[0:5]
Heiko Oberdiek
  • 1,193
  • 8
  • 10
  • True To say, I am just dumbstruck by your answer. It uses so less resources. I would really really like to know where did you learn all this from. Also, your program is really 1000x more efficient than me. Any suggestions for me would be really appreciated. – Krishna Chaudhari Jun 25 '17 at 10:11
  • @KrishnaChaudhari The Python documentation is quite good. Also, I have added some links in the answer for further reading. – Heiko Oberdiek Jun 25 '17 at 10:17