In this article, we will learn about prime numbers and the twin prime conjecture. We will also look at an efficient algorithm for finding the first twin prime pairs up to a number N.
Table of contents:
- Introduction to Prime Numbers
- The Twin Prime Conjecture
- Finding Twin Primes up to a number N
- Space and Time Complexity
Let us get started with Finding the twin primes up to N (Twin Prime Conjecture).
Introduction to Prime Numbers
A prime number is a natural number that is only divisible by one and itself, which means it can only be represented as a product of one and itself
Any number that is not prime is known as a composite number, meaning that it can be formed as a product of smaller numbers. For example, 11 is a prime number as it can only be represented as 11 * 1, but 8 is a composite number as it can be represented as 2 * 4 as well as 8 * 1.
Prime Numbers play important roles in computer science. One of the fields where they are used a lot is cryptography.
The Twin Prime Conjecture
A twin Prime Pair is a pair of prime numbers (a,b) such that a is less than or greater than b by 2. In other words, they are prime numbers pairs such that the difference between them is exactly equal to two.
The Twin prime conjecture states that there are infinitely many twin primes. It is called a conjecture because although the statement might be true, it has not yet been proven to be true.
Finding Twin Primes up to a number N
The steps to find twin primes up to a number N are:
- Identify the first prime numbers up to N
- Identify the Twin prime pairs among the identified primes
- Display result
In order to identify the first prime numbers up to N, We shall use an algorithm known as the Sieve of Eratosthenes. It is an algorithm that finds all the prime numbers up to a number N so it is exactly what we are looking for.
The Sieve of Eratosthenes works by first instantiating all the numbers from 2 to N in a list or grid. Starting from two it iteratively marks all the multiples of every prime number it encounters as composite. By the end, all the numbers that have not been marked are exactly the prime numbers up to N.
We can visualise this with an example.
The above grid has 50 numbers which means we want to find the first prime numbers up to 50.
Following the algorithm and starting from two. We mark all the multiples of two in the grid as they are not prime.
We move to the next unmarked number 3 which we know will be prime, we mark its multiples. There will be overlap but we only have to worry about the multiples not yet marked.
The next unmarked number is 5. We mark the multiples of 5 that haven't yet been marked. You might be noticing a trend, the next prime number always ends up marking a smaller number of multiples because some of its multiples have already been covered by the previous smaller primes.
Lastly, we mark the multiples of seven. After this, we can terminate the algorithm. We know that we can terminate because the square of the next unmarked number 11 is 121 which is greater than 50. All the other smaller multiples of 11 would have already been covered by the smaller primes. and since 11 is the smallest unmarked number with a square greater than 50 we can be safe in our decision to terminate.
After termination, we can be assured that all the unmarked numbers are valid prime numbers.
def findPrimes(N): """ Uses The Sieve of Eratosthenes to find the first prime numbers up to N. input: N, a natural number returns: A set of the first prime numbers up to N """ # Initialise a boolean array where the index maps to a number up to n # All the numbers are first initialised as True # Eventually after the sieve is run, isPrime[i] will be False if i is # composite isPrime = [True for x in range(N + 1)] candidate = 2 # starting from 2 iterate and mark all the multiples while candidate ** 2 <= N: if isPrime[candidate]: for k in range(candidate * 2, n + 1, candidate): isPrime[k] = False candidate += 1 # Use boolean array to filter only the prime numbers to a new List onlyprimes = [i for i in range(2, len(isPrime)) if isPrime[i]] # Convert to a set for constant lookup operations and return return set(onlyprimes)
Now we need to be able to identify twin primes. This is actually easy to do. Everything we need is in the definition. We simply have to iterate through the prime numbers and pick out pairs of prime numbers whose difference is 2.
def findTwinPrimes(primes): """ takes in a set of prime numbers and finds all the twin primes input: A set of prime numbers returns: A list of twinprime tuples """ twinPrimes =  for prime in primes: if prime + 2 in primes: twinPrimes.append((prime, prime + 2)) return twinPrimes
We can tie it all up together and display our results.
def printPrimePairs(n): """ Prints out the first prime pairs up to n """ primes = findPrimes(n) twinprimes = findTwinPrimes(primes) # print results to console for pair in twinprimes: print(pair)
Finally lets Test our method with an actual value
printPrimePairs(50) (3, 5) (5, 7) (11, 13) (17, 19) (29, 31) (41, 43)
Space and Time Complexity
The Sieve of Eratosthenes has a time complexity of O(n log log n) and space complexity of O(n). FindPrimes which implements it also has the same time and space complexity.
FindTwinPrimes has a time complexity of O(d) where d < n it also has a space complexity of O(d)
PrintPrimePairs which encapsulates both functions will be bounded by the higher time complexity so it has a time complexity O(n log log n) and a space complexity of O(n).
With this article at OpenGenus, you must have the complete idea of finding twin primes up to number N and the Twin Prime Conjecture.