Time limit exceeded python - python-3.x

Im a newbie at python and i have a task. Given a number as input, i have to print the prime that belongs in the number/position on a list of primes starting from position 1 and not 0, until the input is 'END'. For example, if the input is 1, output should be the first prime which is 2, if the input is 5, output should be the 5th prime which is 11 and so. It works fine but after 3/4-digit numbers the output has a delay until i get the Error: Time limit exceeded. How can i make it run faster? Here's the code:
def primes_function(n):
primes = []
num = 2
while len(primes) <= n:
x = num // 2
while x > 1:
if num % x == 0:
break
x -= 1
else:
primes.append(num)
num += 1
return primes[n - 1]
#main
while True:
n = input()
if n == 'END':
break
elif n > '0':
n = int(n)
value = primes_function(n)
print(value)
Sorry if i made any mistakes in the description
enter image description here

I combined this answer (1) and this answer (2) to speed up the function. The two key ideas are: When testing primality of a candidate ...
... do not divide by every number (2, 3, 4, 5, 6, ...) but only by the preceding prime numbers (2, 3, 5, ...). Every non-prime number > 2 is has to have some prime factor.
... divide only by numbers that are ≤ sqrt(candidate).
import math
def nth_prime(n):
prime_list = [2]
candidate = 3
while len(prime_list) < n:
max_factor = math.sqrt(candidate)
is_prime = True
for p in prime_list:
if p > max_factor:
break
elif candidate % p == 0:
is_prime = False
break
if is_prime:
prime_list.append(candidate)
candidate += 2
return prime_list[-1]
Benchmark of different solutions:
n=9000 n=15000 n=25000 n=75000
your solution 1m38.455s - - -
linked answer (1) 0m 2.954s 8.291s 22.482s -
linked answer (2) 0m 0.352s 0.776s 1.685s 9.567s
this answer 0m 0.120s 0.228s 0.410s 1.857s
Brij's answer 0m 0.315s 0.340s 0.317s 0.318s
For every n the programs where started from scratch.
As we can see, Brij's Sieve Of Eratosthenes takes a fairly low constant amount of time. If you want to find big prime numbers below a fixed limit then that's the best solution (here n < 78499, as the 78499-th prime number is 1 000 003 which is bigger than the sieve list).
If you also want to find a lot of smaller or medium sized prime numbers or cannot accept a fixed limit then go with this solution.

def SieveOfEratosthenes():
n = 1000000
prime = [True for i in range(n+1)]
p = 2
count = 0
while (p * p <= n):
if (prime[p] == True):
count = count + 1
for i in range(p * p, n+1, p):
prime[i] = False
p += 1
seive = []
for p in range(2, n):
if prime[p]:
seive.append(p)
return seive
def primes_function(n , seive):
return seive[n - 1]
#main
seive = SieveOfEratosthenes()
while True:
n = input()
if n == 'END':
break
elif n > '0':
n = int(n)
value = primes_function(n,seive)
print(value)
Full working : https://ide.geeksforgeeks.org/QTSGQfhFV3
I have precomputed the primes below 10^6 and made a list of primes and accessed the nth prime number by the index.

Related

Why is my simple code taking so much time to execute when i give in large numbers as input?

I have written a simple code to print the largest prime factor of a given number from Project Euler. It works just fine for numbers like 24, but there is no response from the python shell for large numbers!
a=600851475143
b=[]
for i in range(2,600851475143):
if a%i==0:
if i==2:
b.append(i)
continue
for j in range(2,i+1):
if j==i:
b.append(i)
if i%j==0:
break
print(max(b))
print(b)
You can use an algorithm like this to get large factors of prime numbers:
import math
def LLL(N):
p = 1<<N.bit_length()-1
if N == 2:
return 2
if N == 3:
return 3
s = 4
M = pow(p, 2) - 1
for x in range (1, 100000):
s = (((s * N ) - 2 )) % M
xx = [math.gcd(s, N)] + [math.gcd(s*p+x,N) for x in range(7)] + [math.gcd(s*p-x,N) for x in range(1,7)]
try:
prime = min(list(filter(lambda x: x not in set([1]),xx)))
except:
prime = 1
if prime == 1:
continue
else:
break
return N/prime

The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17. Find the sum of all the primes below two million

sum_ans=17
for i in range(11,2000000):
for j in range(2,int(i**0.5)):
if i%j==0:
break
else:
sum_ans+=i
print(sum_ans)
The code i have return gives answer 143064094781 and the correct answer is 142913828922 but i can not figure out where i have gone wrong. So can any one help me.
Range's stop parameter is exclusive. This means that your code is only calculating j from 2 to 1 less than i**0.5. To fix this you can add 1, meaning that your end code will look a little like this, providing the correct output of 142913828922:
sum_ans=17
for i in range(11,2000000):
for j in range(2,int(i**0.5+1)):
if i%j==0:
break
else:
sum_ans+=i
print(sum_ans)
What about about this:
def isPrime(x):
prime = True
for i in range(2, x):
if x % i == 0:
prime = False
break
else:
continue
return prime
primes = (a for a in range(2, 2000000) if isPrime(a))
print(sum(primes))
# output
142913828922
This code will take a few minutes to execute. Buckle up!!
def sumPrimes(n):
sum =0
for i in range(2 ,n):
for j in range(2, int(i / 2) +1):
if (i % j) == 0:
break
else:
sum += i
return sum
print(sumPrimes(2000000))
If you iterating over all numbers below 2 million, you might as well sieve them using the Sieve of Eratoshenes:
from math import ceil, sqrt
def sieve(n):
nums = list(range(2,n+1))
primes = []
p = 2
k = 1+ ceil(sqrt(n))
while p < k:
primes.append(p)
nums = [num for num in nums[1:] if num % p > 0]
p = nums[0]
return primes + nums
Then sum(sieve(2000000)) evaluates to 142913828922. It takes about 5 seconds to run on my machine.

Printing first combination among various combinations

So I have a question:
Given an even number (greater than 2), return two prime numbers whose sum will be equal to given number. There are several combinations possible. Print only first such pair
This is for additional reference:
*Input: The first line contains T, the number of test cases. The following T lines consist of a number each, for which we'll find two prime numbers.
Note: The number would always be an even number.
Output: For every test case print two prime numbers space separated, such that the smaller number appears first. Answer for each test case must be in a new line.
Constraints: 1 ≤ T ≤ 70
2 < N ≤ 10000
Example:
Input:
5, 74, 1024, 66, 8, 9990
Output: 3 71, 3 1021, 5 61, 3 5, 17 9973
Here is what I tried:
import math
def prime(n):
for i in range(2, int(math.sqrt(n)) + 1):
if n % i == 0:
return False
return True
T = int(input("No of inputs: ")) #T is the no of test cases
input_num = []
for i in range(0,T):
input_num.append(input())
lst2= []
if T in range(1,71):
for i in input_num:
if (i in range(3,1000)) and (i % 2 == 0):
for j in range(0,i):
if prime(j) == True:
lst2.append(j)
for x in lst2:
for y in lst2:
if x + y == j:
print(x,end = ' ')
print(y)
This is only taking inputs but not returning outputs.
Also my code is currently intended for all the combinations but what I want is only the first pair and I am not able to do that
I found a more elegant solution to this problem here. Java, C, C++ etc versions of solution is also present there. I am going to give the python3 solution.
# Python 3 program to find a prime number
# pair whose sum is equal to given number
# Python 3 program to print super primes
# less than or equal to n.
# Generate all prime numbers less than n.
def SieveOfEratosthenes(n, isPrime):
# Initialize all entries of boolean
# array as True. A value in isPrime[i]
# will finally be False if i is Not a
# prime, else True bool isPrime[n+1]
isPrime[0] = isPrime[1] = False
for i in range(2, n+1):
isPrime[i] = True
p = 2
while(p*p <= n):
# If isPrime[p] is not changed,
# then it is a prime
if (isPrime[p] == True):
# Update all multiples of p
i = p*p
while(i <= n):
isPrime[i] = False
i += p
p += 1
# Prints a prime pair with given sum
def findPrimePair(n):
# Generating primes using Sieve
isPrime = [0] * (n+1)
SieveOfEratosthenes(n, isPrime)
# Traversing all numbers to find
# first pair
for i in range(0, n):
if (isPrime[i] and isPrime[n - i]):
print(i,(n - i))
return
# Driven program
n = 74
findPrimePair(n)

How can you print the prime numbers from 0 to 100 in python

I am writing a small program to find all prime number from a range from 0 to whatever number the user want. How should I fix my code?
I tried to swap the loop position and the algorithm but it didn't work
g=int(input("type"))
def check_prime(g):
if(g<2):
return False
for x in range(2, g+1):
v=int(math.sqrt(x))
if(x%v==0):
return False
return True
if check_prime(g):
print(x)
I expect when the user input g they will get all the prime numbers from 0 to g and also the program will tell them how many prime numbers found
It's pretty simple, this code below will return you both the count of primes and their values.
g=int(input("type"))
def check_prime(g):
count = 0
primes = []
for number in range(g+1): #considering 'g' is inclusive
primes.append(number)
count += 1
if(number < 2 or number%2 == 0):
primes = primes[:-1]
count -= 1
continue
for x in range(3, number, 2):
if (number % x) == 0:
primes = primes[:-1]
count -= 1
break
return count, primes
print (check_prime(g))

Finding largest prime factor too slow in Python

Question:
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
And I tried to solve it by using the below snippet, its taking long time to run. Is there any best way to solve this problem?
def find_prime(num, ranger):
count = 0
prime = True
for i in range(2, num):
if num % i == 0:
count = count + 1
if count > 1:
prime = False
return prime
return prime
prime_list = []
target = 600851475143
for i in range(2,target ):
if target % i == 0:
print(i)
if find_prime(i,target) and i % 2 == 0:
prime_list.append(i)
print(prime_list)
print(max(prime_list))
Please suggest.
n=600851475143
d=2
while d < n/d:
if n%d==0:
n/=d
else:
d+=1
print n

Resources