DEV Community

Shahrouz Nikseresht
Shahrouz Nikseresht

Posted on • Edited on

Day 4: Optimizing for Speed, Prime Number Checker

Today marks Challenge #4 in my #80DaysOfChallenges. I moved from data structures to number theory, focusing on a classic problem: determining if a number is prime. The primary objective wasn't just to find the answer, but to apply algorithmic optimization to make the checker as fast as possible.


💡 Key Takeaways from Day 4: Efficient Prime Checking

A naive prime checker tests divisibility from 2 up to n-1. This is slow (O(n)). My goal was to implement the two most critical optimizations to dramatically reduce the search space:

1. The Square Root Limit (√n)

The fundamental rule of prime checking is that if a number n has a divisor greater than √n, it must also have a divisor smaller than √n. Therefore, we only need to check for divisors up to √n (or int(n ** 0.5) + 1 in Python). This immediately drops the complexity from O(n) to O(√n).

2. The 6k ± 1 Rule

Beyond the square root optimization, we can eliminate the vast majority of composite numbers immediately.

  • Any number n that is divisible by 2 or 3 (except 2 and 3 themselves) is not prime. We check for this first.
  • All remaining prime numbers greater than 3 can be expressed in the form 6k - 1 or 6k + 1 (where k is any positive integer).

This means we don't need to check i, i+1, i+2, ... instead, we only check potential divisors at intervals of 6: i and i+2.

The Final Optimized Solution

The implementation uses an initial set of checks for the small primes (2 and 3) and their multiples, and then iterates only the necessary divisors up to √n using the 6k ± 1 pattern.

def check_prime(n):
    # Base cases for non-primes
    if n < 2:
        return False

    # Base cases for primes 2 and 3
    if n in (2, 3):
        return True

    # Optimization 1: Eliminate multiples of 2 and 3
    if n % 2 == 0 or n % 3 == 0:
        return False 

    # Optimization 2: Check divisors only up to √(n)
    # The loop step (6) implements the 6k ± 1 rule
    limit = int(n ** 0.5) + 1
    for i in range(5, limit, 6):
        # Check 6k - 1 (i) and 6k + 1 (i + 2)
        if n % i == 0 or n % (i + 2) == 0:
            return False  # Found a divisor

    return True
Enter fullscreen mode Exit fullscreen mode

🎯 Summary and Next Steps

This challenge was a clear illustration of the difference between an algorithm that works and an algorithm that performs. By applying fundamental number theory concepts like the √n limit and the 6k ± 1 rule, we created a function that is dramatically faster than the naive approach, especially for large numbers.

The next step would be exploring even more advanced primality tests, such as the Miller-Rabin test, which uses probability for near-instantaneous checking of massive numbers.

What other classic algorithms rely heavily on clever mathematical tricks for optimization? Let me know in the comments!

Challenge Resources

You can find the full source code for today's challenge on GitHub.

Source Code for Challenge #4: scripts/prime_numbers.py
Main Repository: 80-days-of-challenges
Daily Updates: Twitter/X (@Shahrouzlogs)

Top comments (0)