Bird
Raised Fist0
DSA Rustprogramming~3 mins

Why Sieve of Eratosthenes Find All Primes in DSA Rust?

Choose your learning style10 modes available
The Big Idea

Discover how a simple crossing-off trick can find primes faster than checking each number one by one!

The Scenario

Imagine you want to find all prime numbers up to 100 by checking each number one by one, dividing it by all smaller numbers to see if it's prime.

The Problem

This manual way is very slow and tiring because you do many repeated checks. It's easy to make mistakes and waste time on unnecessary work.

The Solution

The Sieve of Eratosthenes quickly marks off multiples of each prime, so you only check each number once. It's like crossing off all the non-primes in a smart order, saving time and effort.

Before vs After
✗ Before
fn is_prime(n: u32) -> bool {
    if n < 2 { return false; }
    for i in 2..n {
        if n % i == 0 { return false; }
    }
    true
}
✓ After
fn sieve(max: usize) -> Vec<bool> {
    let mut primes = vec![true; max + 1];
    primes[0] = false;
    primes[1] = false;
    for i in 2..=((max as f64).sqrt() as usize) {
        if primes[i] {
            for j in (i*i..=max).step_by(i) {
                primes[j] = false;
            }
        }
    }
    primes
}
What It Enables

This method lets you find all prime numbers up to any limit quickly and easily, unlocking fast math and cryptography tasks.

Real Life Example

When creating secure passwords or encrypting messages, computers need to find large prime numbers fast. The sieve helps find these primes efficiently.

Key Takeaways

Manual prime checks are slow and repetitive.

Sieve of Eratosthenes marks multiples to skip unnecessary checks.

It speeds up finding all primes up to a number efficiently.

Practice

(1/5)
1. What is the main purpose of the Sieve of Eratosthenes algorithm?
easy
A. To sort a list of numbers in ascending order
B. To find the greatest common divisor of two numbers
C. To find all prime numbers up to a given limit
D. To calculate the factorial of a number

Solution

  1. Step 1: Understand the algorithm's goal

    The Sieve of Eratosthenes is designed to identify prime numbers efficiently.
  2. Step 2: Recognize the output of the algorithm

    It marks multiples of primes as non-prime, leaving primes unmarked up to a limit.
  3. Final Answer:

    To find all prime numbers up to a given limit -> Option C
  4. Quick Check:

    Sieve of Eratosthenes = Find primes [OK]
Hint: Sieve marks multiples to find primes fast [OK]
Common Mistakes:
  • Confusing it with sorting algorithms
  • Thinking it calculates factorials
  • Assuming it finds divisors instead of primes
2. Which Rust code snippet correctly initializes a boolean vector is_prime of size n+1 with all values set to true except for indices 0 and 1?
easy
A. let is_prime = vec![false; n+1]; is_prime[0] = true; is_prime[1] = true;
B. let mut is_prime = vec![true; n+1]; is_prime[0] = false; is_prime[1] = false;
C. let mut is_prime = vec![true; n]; is_prime[0] = false; is_prime[1] = false;
D. let mut is_prime = vec![false; n]; is_prime[0] = true; is_prime[1] = true;

Solution

  1. Step 1: Initialize vector with true values

    We want a mutable vector of size n+1 with all true values initially.
  2. Step 2: Set indices 0 and 1 to false

    Since 0 and 1 are not prime, we set those positions to false.
  3. Final Answer:

    let mut is_prime = vec![true; n+1]; is_prime[0] = false; is_prime[1] = false; -> Option B
  4. Quick Check:

    Initialize true vector and mark 0,1 false [OK]
Hint: Use vec![true; n+1] and set 0,1 false [OK]
Common Mistakes:
  • Using size n instead of n+1
  • Not making vector mutable
  • Setting wrong indices to true/false
3. What will be the output of the following Rust code snippet that uses the Sieve of Eratosthenes to find primes up to 10?
let n = 10;
let mut is_prime = vec![true; n+1];
is_prime[0] = false;
is_prime[1] = false;
for i in 2..=((n as f64).sqrt() as usize) {
    if is_prime[i] {
        let mut j = i * i;
        while j <= n {
            is_prime[j] = false;
            j += i;
        }
    }
}
let primes: Vec<usize> = is_prime.iter().enumerate()
    .filter(|&(_, &prime)| prime)
    .map(|(index, _)| index)
    .collect();
println!("{:?}", primes);
medium
A. [2, 3, 5, 7]
B. [1, 2, 3, 5, 7]
C. [2, 3, 4, 5, 7]
D. [0, 2, 3, 5, 7]

Solution

  1. Step 1: Initialize and mark non-primes

    Indices 0 and 1 are false. Loop marks multiples of 2 and 3 as false.
  2. Step 2: Collect indices marked true

    Only 2, 3, 5, and 7 remain true and are collected as primes.
  3. Final Answer:

    [2, 3, 5, 7] -> Option A
  4. Quick Check:

    Primes up to 10 = [2, 3, 5, 7] [OK]
Hint: Primes under 10 are 2,3,5,7 only [OK]
Common Mistakes:
  • Including 1 or 0 as prime
  • Including 4 which is not prime
  • Not starting j from i*i
4. Identify the bug in this Rust code snippet implementing the Sieve of Eratosthenes for n = 15:
let n = 15;
let mut is_prime = vec![true; n+1];
is_prime[0] = false;
is_prime[1] = false;
for i in 2..n {
    if is_prime[i] {
        let mut j = i * 2;
        while j <= n {
            is_prime[j] = false;
            j += i;
        }
    }
}
medium
A. Indices 0 and 1 should be set to true
B. The vector size should be n, not n+1
C. The outer loop should run from 2 to sqrt(n), not 2 to n
D. The inner loop should start from i * i, not i * 2

Solution

  1. Step 1: Check inner loop start index

    Starting from i*2 marks some numbers multiple times, less efficient.
  2. Step 2: Correct start is i*i for marking multiples

    Because smaller multiples are already marked by smaller primes.
  3. Final Answer:

    The inner loop should start from i * i, not i * 2 -> Option D
  4. Quick Check:

    Start marking multiples from i*i for efficiency [OK]
Hint: Start marking multiples from i squared [OK]
Common Mistakes:
  • Starting inner loop from i*2 wastes time
  • Looping outer from 2 to n instead of sqrt(n)
  • Wrong vector size causing index errors
5. You want to find all prime numbers up to 50 using the Sieve of Eratosthenes in Rust. After running the sieve, you want to return a vector of primes but exclude the prime number 2 from the result. Which modification to the code below achieves this?
let n = 50;
let mut is_prime = vec![true; n+1];
is_prime[0] = false;
is_prime[1] = false;
for i in 2..=((n as f64).sqrt() as usize) {
    if is_prime[i] {
        let mut j = i * i;
        while j <= n {
            is_prime[j] = false;
            j += i;
        }
    }
}
let primes: Vec<usize> = is_prime.iter().enumerate()
    .filter(|&(_, &prime)| prime)
    .map(|(index, _)| index)
    .collect();
hard
A. Add a filter after collecting primes: primes.into_iter().filter(|&x| x != 2).collect()
B. Set is_prime[2] = false before the outer loop
C. Start outer loop from 3 instead of 2
D. Remove is_prime[0] = false line

Solution

  1. Step 1: Understand the sieve marks primes correctly

    All primes including 2 are marked true in is_prime.
  2. Step 2: Exclude 2 after collecting primes

    Filtering out 2 after collecting primes avoids affecting sieve logic.
  3. Final Answer:

    Add a filter after collecting primes: primes.into_iter().filter(|&x| x != 2).collect() -> Option A
  4. Quick Check:

    Filter out 2 after sieve to exclude it [OK]
Hint: Filter out 2 after collecting primes [OK]
Common Mistakes:
  • Setting is_prime[2] = false breaks sieve correctness
  • Starting loop from 3 misses marking multiples of 2
  • Removing is_prime[0] = false causes wrong prime marking
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard