5 Best Ways to Check Whether Given Three Numbers Are Adjacent Primes in Python

πŸ’‘ Problem Formulation: In this article, we explore the challenge of determining whether a set of three inputted numbers constitute consecutive prime numbers. Specifically, the Python methods detailed here will answer whether the numbers are prime and if they follow one another in the sequence of prime numbers. For instance, given the input (17, 19, 23), the desired output would confirm that these are indeed adjacent prime numbers.

Method 1: Traditional Prime Checking with a Twist

Method 1 uses the classical approach to check for primes and then assesses adjacency by comparing differences. It involves iterating over a range up to the square root of the number for prime validation and ensures the differences between consecutive prime candidates are as expected for adjacent primes.

Here’s an example:

def is_prime(num):
    if num < 2:
        return False
    for i in range(2, int(num**0.5) + 1):
        if num % i == 0:
            return False
    return True

def are_adjacent_primes(primes):
    primes = sorted(primes)
    return all(is_prime(num) for num in primes) and all(primes[i+1] - primes[i] in (2, 4) for i in range(len(primes)-1))

# Example usage:
primes_to_check = (29, 31, 37)
print(are_adjacent_primes(primes_to_check))

Output: True

This snippet defines a function is_prime() which determines the primality of a number. The second function, are_adjacent_primes(), checks for prime numbers in a sorted tuple and verifies that they are consecutive. The example usage shows that 29, 31, and 37 are indeed adjacent primes.

Method 2: Sieve of Eratosthenes Optimization

This method employs the Sieve of Eratosthenes to precompute the primes up to a certain limit, providing a more efficient way to check primality for multiple numbers. This is effective if we are running the adjacency check for numerous sets of numbers within a known range.

Here’s an example:

def sieve_eratosthenes(limit):
    sieve = [True] * (limit + 1)
    sieve[0], sieve[1] = False, False
    for i in range(2, int(limit**0.5)+1):
        if sieve[i]:
            for j in range(i*i, limit+1, i):
                sieve[j] = False
    return sieve

def are_adjacent_primes(primes):
    limit = max(primes)
    sieve = sieve_eratosthenes(limit)
    primes = sorted(primes)
    return all(sieve[num] for num in primes) and all(primes[i+1] - primes[i] in (2, 4) for i in range(len(primes)-1))

# Example usage:
primes_to_check = (29, 31, 37)
print(are_adjacent_primes(primes_to_check))

Output: True

This snippet introduces a sieve_eratosthenes() function that creates a sieve for all numbers up to the maximum prime candidate to rapidly check for primality. The are_adjacent_primes() function then verifies if the sorted primes are adjacent. Again, for the numbers 29, 31, and 37, this method confirms they are adjacent primes.

Method 3: Utilizing a Prime Generator

This method generates prime numbers on-the-fly using a generator until it surpasses the largest of the three numbers. This is particularly useful if the numbers are large and not close to each other, as it avoids unnecessary calculations.

Here’s an example:

def prime_generator():
    D = {}
    q = 2
    while True:
        if q not in D:
            yield q
            D[q*q] = [q]
        else:
            for p in D[q]:
                D.setdefault(p+q,[]).append(p)
            del D[q]
        q += 1

def are_adjacent_primes(primes):
    primes = sorted(primes)
    gen = prime_generator()
    generated_primes = [next(gen) for _ in range(primes[-1])]
    return all(num in generated_primes for num in primes) and all(primes[i+1] - primes[i] in (2, 4) for i in range(len(primes)-1))

# Example usage:
primes_to_check = (97, 101, 103)
print(are_adjacent_primes(primes_to_check))

Output: True

Here, prime_generator() successively yields prime numbers using a dictionary to track multiples. are_adjacent_primes() then utilizes this generator to create a list of primes until the largest given number is reached, and verifies adjacency among the inputted numbers. The code confirms that 97, 101, and 103 are adjacent primes.

Method 4: Using Library Functions

Python’s rich ecosystem includes libraries such as SymPy, which can be used to check for primes with optimized functions. This method is very straightforward and is best when looking for a quick implementation without reinventing the wheel.

Here’s an example:

from sympy import primerange

def are_adjacent_primes(primes):
    primes = sorted(primes)
    prime_list = list(primerange(primes[0], primes[-1]+1))
    return prime_list == primes

# Example usage:
primes_to_check = (41, 43, 47)
print(are_adjacent_primes(primes_to_check))

Output: True

The snippet utilizes the primerange() function from the SymPy library, generating all prime numbers in the specified range. The check then simply compares the sorted list of user-provided primes to the range generated by SymPy, returning whether they match exactly. This confirms the adjacency of the primes 41, 43, and 47.

Bonus One-Liner Method 5: Pythonic Approach with List Comprehension

Python is well-known for its one-liner capabilities. This method shows how one could use list comprehension along with Python’s built-in all() function to determine the adjacency of prime numbers in a single statement.

Here’s an example:

from sympy import isprime

primes_to_check = (11, 13, 17)
are_adjacent_primes = all(isprime(num) for num in primes_to_check) and sorted(primes_to_check)[1] - sorted(primes_to_check)[0] == 2 and sorted(primes_to_check)[2] - sorted(primes_to_check)[1] == 4

print(are_adjacent_primes)

Output: True

The one-liner uses isprime() from SymPy for primality checking and Python’s list comprehension and all() function for adjacency verification. The differences between the numbers are hardcoded into the one-liner, assuming that the middle number will always have a difference of 2 with the first and a difference of 4 with the third, which is the case for prime triplets. This affirms the adjacency of the primes 11, 13, and 17.

Summary/Discussion

  • Method 1: Traditional Prime Checking. Strengths: simple and straightforward. Weaknesses: can be inefficient for larger numbers due to repeated computations for primality.
  • Method 2: Sieve of Eratosthenes. Strengths: efficient for batches within a range. Weaknesses: not as efficient for isolated, large number checks.
  • Method 3: Prime Generator. Strengths: efficient for large, spaced-out numbers. Weaknesses: slightly complex implementation.
  • Method 4: Library Functions. Strengths: quick and easy to implement with powerful external libraries. Weaknesses: dependency on third-party libraries.
  • Bonus Method 5: Pythonic One-Liner. Strengths: concise and elegant code. Weaknesses: less readable and inflexible to changes.