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

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

Related

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.

Can any one help me with this one . I was trying to write a prog for finding 'LCM'. I want to equate these variable

Here c and d basically represent tables of respective number for variable a and b...i am trying to match the least common product from these table.Please help me figure it out
a=(input('your first no: '))
b=(input('your second no: '))
for i in range(1,100):
c=a*i
d=b*i
if (c==d):
print('lcm is')
Here is a program that will work. It will also calculate the LCM of more than two numbers.
from collections import Counter
from operator import mul
from functools import reduce
def primeFactors(n):
if not isinstance(n, int) or n < 1:
raise ValueError("must be positive integer")
factors = []
while n % 2 == 0:
factors.append(2)
n /= 2
i = 3
while n != 1:
while n % i == 0:
factors.append(i)
n /= i
i += 2
return factors
def get_lcm(numbers):
factorisations = [Counter(primeFactors(n)) for n in numbers]
primes = frozenset().union(*(set(x.keys()) for x in factorisations))
primes_to_max_powers = (p ** max(*(x.get(p,0) for x in factorisations))
for p in primes)
return reduce(mul, primes_to_max_powers, 1)
a = int(input('your first no: '))
b = int(input('your second no: '))
print('lcm is', get_lcm([a, b]))
Or you can do this instead but it might be a bit slower:
a = input('your first no: ')
b = input('your second no: ')
for i in range(max(a, b), a * b + 1):
if i % a == 0 and i % b == 0:
lcm = i
break
print('lcm is ', lcm)
Use the formula lcm(a,b) = a⋅b / gcd(a,b). Python has a gcd function in the standard library:
from fractions import gcd
def least_common_multiple(a, b):
return a * b / gcd(a, b)
Since Python 3.6, it's arguably preferable to use the gcd builtin from math:
try:
from math import gcd
except ImportError:
from fractions import gcd
def least_common_multiple(a, b):
return a * b / gcd(a, b)

How can i sum co-prime numbers in a pair

I have this list
a = [1,2,3,4,5,6,7,8,9]
I want to find out that how many co-prime pair elements of the list add up to sum=9
Ex, (1+8) = 9 , (2+7) = 9 , (3+6)=9 , (4+5)=9, (5+4)=9 , (6+3)=9, (7+2)=9 , (8+1)=9
Note that i don't want (3+6) as they are prime numbers. And i also don't want (7+2)=9 as it has already occurred (means 2,7 has been already taken in account)
I tried this But it takes repeated values too.
a = [1,2,3,4,5,6,7,8,9]
count=0
for m in a:
for n in a:
total=m+n
if(total==9):
s=str(m) + '+'+ str(n) + "="
print(s , m+n)
count=count+1
print("Count =" ,count)
The result should have count=3
Your mistake is in the way of doing the loops, so you repeat values.
Try this:
#from math import gcd as bltin_gcd
a = [1,2,3,4,5,6,7,8,9]
count = 0
def __gcd(a, b):
# Everything divides 0
if (a == 0 or b == 0): return 0
# base case
if (a == b): return a
# a is greater
if (a > b):
return __gcd(a - b, b)
return __gcd(a, b - a)
# Only python 3
# def coprime(a, b):
# return bltin_gcd(a, b) == 1
for i in range(0,9):
for j in range(i+1,9):
if __gcd(a[i], a[j]) == 1 and a[i] + a[j] == 9:
count += 1
print str(a[i]) + ' ' + str(a[j])
print 'Count = ' + str(count)
In number theory, two integers a and b are said to be relatively prime, mutually prime, or coprime if the only positive integer that divides both of them is 1. Consequently, any prime number that divides one does not divide the other. This is equivalent to their greatest common divisor being 1.
for m in a:
for n in a:
You are not selecting pairs by using this loops, ie. you are picking the first element in both the outer and inner loop during your first iteration.
if(total==9):
You are not checking the condition if the selected pair of numbers are coprime. You are only verifying the sum.
A pythonic solution may be obtained with a one-liner:
from math import gcd
a = [1,2,3,4,5,6,7,8,9]
pairs = [(m,n) for m in a for n in a if n > m and m+n == 9 and gcd(m,n) == 1]
Result :
pairs --> [(1, 8), (2, 7), (4, 5)]
If you are sure to never, never need the pairs but only the number of pairs (as written in the OP), the most efficient solution may be:
count = len([1 for m in a for n in a if n > m and m+n == 9 and gcd(m,n) == 1])
EDIT : I inversed the three conditions in the if statement for improved benefit from lazy boolean evaluation
You can solve this if you have something that calculates your prime factorization in python:
from functools import lru_cache
# cached function results for pime factorization of identical nr
#lru_cache(maxsize=100)
def factors(nr):
# adapted from https://stackoverflow.com/a/43129243/7505395
i = 2
factors = []
while i <= nr:
if (nr % i) == 0:
factors.append(i)
nr = nr / i
else:
i = i + 1
return factors
start_at = 1
end_at = 9
total = 9
r = range(start_at, end_at+1)
# create the tuples we look for, smaller number first - set so no duplicates
tupls = set( (a,b) if a<b else (b,a) for a in r for b in r if a+b == total)
for n in tupls:
a,b = n
f_a = set(factors(a))
f_b = set(factors(b))
# if either set contains the same value, the f_a & f_b will be truthy
# so not coprime - hence skip it
if f_a & f_b:
continue
print(n)
Output:
(2, 7)
(1, 8)
(4, 5)

How to find number in list which has the biggest number of prime?

I want to write a program that receives 10 entries and at the end it should print the number that has the greatest number of prime factors along with the number of its prime factors in the output. And, if some of the inputs have the same condition, the program will print the biggest one.
The code that I wrote executed all conditions except the final condition.
How should I write a code for a case where two numbers have the same numbers of prime factors (when I want the bigger number to be my output)?
For example both 678 and 84 have 3 prime factors . The output of my code is 84, while I want the output to be 678 (the bigger number).
input:
123
43
54
12
76
84
98
678
543
231
Correct output:
678 3
but my output:
84 3
a = [0,0,0,0,0,0,0,0,0,0]
#a = [123,43,54,12,76,84,98,678,543,231]
b = [0,0,0,0,0,0,0,0,0,0]
def is_first (number):
Prime_number= 0
for m in range(1, (number //2)+1, 1):
if number % m == 0:
Prime_number += 1
if Prime_number > 1:
is_prime = 0
else:
is_prime = 1
return is_prime
for i in range(0,10,1):
a[i] = input()
for j in a:
numbers= 0
for k in range(2, int(j)//2, 1):
if int(j) % k == 0:
if is_first (k) == 1:
numbers += 1
b[a.index(j)] = numbers
index_of_same = [i for i, e in enumerate(b) if e == max(b)]
n = []
for t in index_of_same:
n.append(a[t])
print(str(max(n))+ ' ' + str(max(b)))
When you append the numbers that have the highest number of prime factors to the list n, you are storing them as strings and not integers. Hence when you do the max() function on n, which holds 84,678 and 231, 84 is returned. I would suggest you to convert the numbers using int(), when storing into n and then perform the max()function on it. Just tweak your code as under:
for t in index_of_same:
n.append(int(a[t]))
Your code is cumbersome IMO, so I'd like to suggest a simpler version:
def getNumOfFactors(n):
num = 0
factor = 1
while n > 1:
factor += 1
if n % factor == 0:
num += 1
n /= factor
while n % factor == 0:
n /= factor
return num
def getMaxValue(values):
factors = [getNumOfFactors(n) for n in values]
tuples = zip(factors,values)
sorted_tuples = sorted([tuple for tuple in tuples],key=lambda x: x[0])
max_tuples = [tuple for tuple in sorted_tuples if tuple[0] == sorted_tuples[-1][0]]
sorted_max_tuples = sorted([tuple for tuple in max_tuples],key=lambda x: x[1])
return sorted_max_tuples[-1]
maxValue = getMaxValue([123,43,54,12,76,84,98,678,543,231])
print(maxValue)

Time limit exceeded python

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.

Resources