Discover how a simple crossing-off trick can find primes faster than checking each number one by one!
Why Sieve of Eratosthenes Find All Primes in DSA Rust?
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.
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 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.
fn is_prime(n: u32) -> bool {
if n < 2 { return false; }
for i in 2..n {
if n % i == 0 { return false; }
}
true
}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
}This method lets you find all prime numbers up to any limit quickly and easily, unlocking fast math and cryptography tasks.
When creating secure passwords or encrypting messages, computers need to find large prime numbers fast. The sieve helps find these primes efficiently.
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
Sieve of Eratosthenes algorithm?Solution
Step 1: Understand the algorithm's goal
The Sieve of Eratosthenes is designed to identify prime numbers efficiently.Step 2: Recognize the output of the algorithm
It marks multiples of primes as non-prime, leaving primes unmarked up to a limit.Final Answer:
To find all prime numbers up to a given limit -> Option CQuick Check:
Sieve of Eratosthenes = Find primes [OK]
- Confusing it with sorting algorithms
- Thinking it calculates factorials
- Assuming it finds divisors instead of primes
is_prime of size n+1 with all values set to true except for indices 0 and 1?Solution
Step 1: Initialize vector with true values
We want a mutable vector of size n+1 with all true values initially.Step 2: Set indices 0 and 1 to false
Since 0 and 1 are not prime, we set those positions to false.Final Answer:
let mut is_prime = vec![true; n+1]; is_prime[0] = false; is_prime[1] = false; -> Option BQuick Check:
Initialize true vector and mark 0,1 false [OK]
- Using size n instead of n+1
- Not making vector mutable
- Setting wrong indices to true/false
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);Solution
Step 1: Initialize and mark non-primes
Indices 0 and 1 are false. Loop marks multiples of 2 and 3 as false.Step 2: Collect indices marked true
Only 2, 3, 5, and 7 remain true and are collected as primes.Final Answer:
[2, 3, 5, 7] -> Option AQuick Check:
Primes up to 10 = [2, 3, 5, 7] [OK]
- Including 1 or 0 as prime
- Including 4 which is not prime
- Not starting j from i*i
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;
}
}
}Solution
Step 1: Check inner loop start index
Starting from i*2 marks some numbers multiple times, less efficient.Step 2: Correct start is i*i for marking multiples
Because smaller multiples are already marked by smaller primes.Final Answer:
The inner loop should start from i * i, not i * 2 -> Option DQuick Check:
Start marking multiples from i*i for efficiency [OK]
- Starting inner loop from i*2 wastes time
- Looping outer from 2 to n instead of sqrt(n)
- Wrong vector size causing index errors
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();Solution
Step 1: Understand the sieve marks primes correctly
All primes including 2 are marked true inis_prime.Step 2: Exclude 2 after collecting primes
Filtering out 2 after collecting primes avoids affecting sieve logic.Final Answer:
Add a filter after collecting primes: primes.into_iter().filter(|&x| x != 2).collect() -> Option AQuick Check:
Filter out 2 after sieve to exclude it [OK]
- 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
Ready to prove it?
Pass the test and this pattern moves unknown
