-2
#code for SieveOfEratosthenes here

SieveOfEratosthenes=SieveOfEratosthenes(999999)

t = int(input().strip())
for a0 in range(t):
  N= input()
  prime=set()
  for w in range(1,7):
    for i in range(0,len(N)):
      substring=int(N[i:i+w])
      if(N[i:i+w][-1]!=4 and N[i:i+w][-1]!=6 and N[i:i+w][-1]!=8 and N[i:i+w][-1]!=0):
        if(len(str(substring))==w and substring in SieveOfEratosthenes):
          prime.add(substring)
  print(len(prime))

This code is working correctly but timesout for bigger.
Q: How to optimize it?

Spears
  • 1,714
  • 1
  • 13
  • 23

1 Answers1

0

You do not give examples of your test cases, so we cannot know when it fails. But here I present a optimized version of your code; at least I think I understood what you are trying to do.

First, I present a implementation of the sieve (not my own invention, the source is in the functions docstring):

def generate_primes():
    """
    Generate an infinite sequence of prime numbers.

    Sieve of Eratosthenes
    Code by David Eppstein, UC Irvine, 28 Feb 2002
    http://code.activestate.com/recipes/117119/
    https://stackoverflow.com/a/568618/9225671
    """
    # 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

Python code usually runs faster if you do not use global variables, so I put all the code inside a function. I also:

  • generate a set (not a list, because set provides faster membership checking) of prime numbers at the beginning.
  • removed the line

    if(N[i:i+w][-1]!=4 and N[i:i+w][-1]!=6 and N[i:i+w][-1]!=8 and N[i:i+w][-1]!=0):
    

    from your code, because it does nothing usefull; N[i:i+w][-1] is the last char of the substring, it has type str and will thus never be equal to an int.

My version looks like this:

def func():
    max_prime_number = 10**6
    primes_set = set()
    for n in generate_primes():
        if n < max_prime_number:
            primes_set.add(n)
        else:
            break
    print('len(primes_set):', len(primes_set))

    while True:
        print()
        input_str = input('Enter "input_str":').strip()
        if len(input_str) == 0:
            break

        print('Searching prime substring in', input_str)
        prime_substrings = set()
        for w in range(1, 7):
            for i in range(len(input_str)):
                n = int(input_str[i:i+w])
                sub_str = str(n)        # may be shorter than 'w' if it had leading zeros

                if len(sub_str) == w:
                    if n in primes_set:
                        prime_substrings.add(sub_str)
        print('len(prime_substrings):', len(prime_substrings))
Ralf
  • 13,322
  • 4
  • 31
  • 55
  • Note: my code will fail if you input strings that cannot be converted to integers; no error catching is done. – Ralf Mar 01 '19 at 10:35