patternpythonMinor
Simple prime number search with trial division
Viewed 0 times
numbersimpledivisionsearchwithprimetrial
Problem
I made a primality tester with trial division. I'm trying to make it as fast as possible and have reached the point now where I'm out of ideas.
I use the generator approach and not lists because I found out that it's awfully slow to generate and checklists for big ranges.
Does someone have ideas on how to improve the
I use the generator approach and not lists because I found out that it's awfully slow to generate and checklists for big ranges.
Does someone have ideas on how to improve the
is_prime_td() and seeker() functions? I left some comments in the code to explain why I did it like this.#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Made for Python 2.7.x
See __main__ block at the end of this
script to change the range to be searched.
'''
from math import sqrt as math_sqrt
def is_prime_td(num):
''' Test if a number is a prime with Trial Division.
num: The number to be tested.
Returns True if num is a prime and False if not.
'''
# No prime if smaller than 2
if num = 2:
num = num_start
else:
num = 2
try:
while num <= num_end:
if is_prime_td(num):
yield num
# Since there are no even primes except 2, we only want to
# test odd numbers in the loop. Increment accordingly so we never
# test even numbers and thus saving some time.
if num % 2 == 0:
num += 1
else:
num += 2
except KeyboardInterrupt:
pass
if __name__ == '__main__':
# Define the range to be searched here.
num_start = 0
num_end = 100
# Print only positive findings.
for num in seeker(num_start, num_end):
print numSolution
Instead of doing this you should instead use a sieve, where you filter the output. It would make the code much simpler, and would make it much faster.
Your comments are useless at best. If you know two languages it'd not make sense to say the same thing in both. Which is what you are doing here. Instead what you want to use comments for, is for high-level overviews of your code.
Say you create a primality test which is heavily optimized, you would want to put a comment on the hard to read parts. Such as your
To improve the actual code, I'd:
Your comments are useless at best. If you know two languages it'd not make sense to say the same thing in both. Which is what you are doing here. Instead what you want to use comments for, is for high-level overviews of your code.
Say you create a primality test which is heavily optimized, you would want to put a comment on the hard to read parts. Such as your
sqrt part.To improve the actual code, I'd:
- Remove unneeded comment.
- Change the
whileto not square rootnumeach iteration.
- Change the code to use the less accurate
**operator, rather thanmath.sqrt. You're usingintand adding by 1 anyway, so it won't make a difference.
- Change
seekertoyeild 2if it's within the domain.
- Change
seekerto use aforloop, to simplify the code. As with the above you don't need to increment by one ever.
- Move the keyboard interrupt code out of the function, into the main. As functions are meant to do one thing, not two.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Made for Python 2.7.x
See __main__ block at the end of this
script to change the range to be searched.
"""
def is_prime(num):
"""
Test if a number is a prime with Trial Division.
num: The number to be tested.
Returns True if num is a prime and False if not.
"""
if num < 2:
return False
if num == 2:
return True
if num % 2 == 0:
return False
# Check if number is divisible by any odd number,
# from one to the square root of the number.
# as one of a or b will be in this range,
# for all a and b that are `a * b = num`.
for i in range(3, int(num ** 0.5) + 2, 2):
if num % i == 0:
return False
return True
def seeker(num_start, num_end):
"""
Search for primes from and including num_start to num_end.
Uses 'is_prime_td()'.
"""
# Force `num_start` to be odd with xor, ^. And go up in twos.
if num_start <= 2 <= num_end:
yield 2
for i in range(max(3, num_start ^ 1), num_end + 1, 2):
if is_prime_td(num):
yield num
if __name__ == '__main__':
num_start = 0
num_end = 100
try:
for num in seeker(num_start, num_end):
print num
except KeyboardInterupt:
passCode Snippets
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Made for Python 2.7.x
See __main__ block at the end of this
script to change the range to be searched.
"""
def is_prime(num):
"""
Test if a number is a prime with Trial Division.
num: The number to be tested.
Returns True if num is a prime and False if not.
"""
if num < 2:
return False
if num == 2:
return True
if num % 2 == 0:
return False
# Check if number is divisible by any odd number,
# from one to the square root of the number.
# as one of a or b will be in this range,
# for all a and b that are `a * b = num`.
for i in range(3, int(num ** 0.5) + 2, 2):
if num % i == 0:
return False
return True
def seeker(num_start, num_end):
"""
Search for primes from and including num_start to num_end.
Uses 'is_prime_td()'.
"""
# Force `num_start` to be odd with xor, ^. And go up in twos.
if num_start <= 2 <= num_end:
yield 2
for i in range(max(3, num_start ^ 1), num_end + 1, 2):
if is_prime_td(num):
yield num
if __name__ == '__main__':
num_start = 0
num_end = 100
try:
for num in seeker(num_start, num_end):
print num
except KeyboardInterupt:
passContext
StackExchange Code Review Q#149783, answer score: 3
Revisions (0)
No revisions yet.