diff --git a/src/utils/objects/sieve_of_atkin.rs b/src/utils/objects/sieve_of_atkin.rs index b1fd74b..88489f5 100644 --- a/src/utils/objects/sieve_of_atkin.rs +++ b/src/utils/objects/sieve_of_atkin.rs @@ -46,35 +46,32 @@ impl SieveOfAtkin { sieve_of_atkin } fn init(&mut self) { - let (tx, rx) = std::sync::mpsc::channel(); + let mut sieve3 = self.sieve.clone(); + let mut sieve2 = self.sieve.clone(); + let sieve1 = self.sieve.as_mut_slice(); std::thread::scope(|s| { - let (tx1, tx2, tx3) = (tx.clone(), tx.clone(), tx.clone()); - let sieve_len = self.sieve.len() as i64; - s.spawn(move || { + s.spawn(|| { for delta in [1, 13, 17, 29, 37, 41, 49, 53] { - SieveOfAtkin::algorithm_3_1(delta, sieve_len, &tx1); + SieveOfAtkin::algorithm_3_1(delta, sieve1); } }); - s.spawn(move || { + s.spawn(|| { for delta in [7, 19, 31, 43] { - SieveOfAtkin::algorithm_3_2(delta, sieve_len, &tx2); + SieveOfAtkin::algorithm_3_2(delta, &mut sieve2); } }); - s.spawn(move || { + s.spawn(|| { for delta in [11, 23, 47, 59] { - SieveOfAtkin::algorithm_3_3(delta, sieve_len, &tx3); + SieveOfAtkin::algorithm_3_3(delta, &mut sieve3); } }); - drop(tx); - for (k, delta) in rx { - self.sieve[k as usize] ^= 1u16 << SieveOfAtkin::SHIFTS[delta as usize]; - } }); // Mark composite all numbers divisible by the squares of primes. let mut num: usize = 1; let mut offset = SieveOfAtkin::OFFSETS.iter().cycle(); 'sieve: for sieve_idx in 0..self.sieve.len() { + self.sieve[sieve_idx] ^= sieve2[sieve_idx] ^ sieve3[sieve_idx]; for shift in 0..16 { if self.sieve[sieve_idx] >> shift & 1 == 1 { let num_sqr = num.pow(2); @@ -92,40 +89,40 @@ impl SieveOfAtkin { } } } - fn algorithm_3_1(delta: i32, sieve_len: i64, tx: &std::sync::mpsc::Sender<(i64, i32)>) { + fn algorithm_3_1(delta: i32, sieve: &mut [u16]) { for f in 1..=15 { for g in (1..=30).step_by(2) { let quadratic = 4 * f * f + g * g; if delta == quadratic % 60 { - SieveOfAtkin::algorithm_4_1(delta, f, g, quadratic / 60, sieve_len, tx); + SieveOfAtkin::algorithm_4_1(delta, f, g, quadratic / 60, sieve); } } } } - fn algorithm_3_2(delta: i32, sieve_len: i64, tx: &std::sync::mpsc::Sender<(i64, i32)>) { + fn algorithm_3_2(delta: i32, sieve: &mut [u16]) { for f in (1..=10).step_by(2) { for g in [2, 4, 8, 10, 14, 16, 20, 22, 26, 28] { let quadratic = 3 * f * f + g * g; if delta == quadratic % 60 { - SieveOfAtkin::algorithm_4_2(delta, f, g, quadratic / 60, sieve_len, tx); + SieveOfAtkin::algorithm_4_2(delta, f, g, quadratic / 60, sieve); } } } } - fn algorithm_3_3(delta: i32, sieve_len: i64, tx: &std::sync::mpsc::Sender<(i64, i32)>) { + fn algorithm_3_3(delta: i32, sieve: &mut [u16]) { for (f, gstart) in (1..=10).zip([2, 1].into_iter().cycle()) { for g in (gstart..=30).step_by(2) { let quadratic = 3i32 * f * f - g * g; // Remainder can be negative, so perform modulo operation. if delta == quadratic.rem_euclid(60) { - SieveOfAtkin::algorithm_4_3(delta, f, g, quadratic.div_euclid(60), sieve_len, tx); + SieveOfAtkin::algorithm_4_3(delta, f, g, quadratic.div_euclid(60), sieve); } } } } - fn algorithm_4_1(delta: i32, f: i32, g: i32, h: i32, sieve_len: i64, tx: &std::sync::mpsc::Sender<(i64, i32)>) { + fn algorithm_4_1(delta: i32, f: i32, g: i32, h: i32, sieve: &mut [u16]) { let (mut x, mut y0, mut k0) = (f as i64, g as i64, h as i64); - while k0 < sieve_len { + while k0 < sieve.len() as i64 { (k0, x) = (k0 + 2 * x + 15, x + 15); } loop { @@ -137,15 +134,15 @@ impl SieveOfAtkin { (k0, y0) = (k0 + y0 + 15, y0 + 30); } let (mut k, mut y) = (k0, y0); - while k < sieve_len { - tx.send((k, delta)).unwrap(); + while k < sieve.len() as i64 { + sieve[k as usize] ^= 1u16 << SieveOfAtkin::SHIFTS[delta as usize]; (k, y) = (k + y + 15, y + 30); } } } - fn algorithm_4_2(delta: i32, f: i32, g: i32, h: i32, sieve_len: i64, tx: &std::sync::mpsc::Sender<(i64, i32)>) { + fn algorithm_4_2(delta: i32, f: i32, g: i32, h: i32, sieve: &mut [u16]) { let (mut x, mut y0, mut k0) = (f as i64, g as i64, h as i64); - while k0 < sieve_len { + while k0 < sieve.len() as i64 { (k0, x) = (k0 + x + 5, x + 10); } loop { @@ -157,16 +154,16 @@ impl SieveOfAtkin { (k0, y0) = (k0 + y0 + 15, y0 + 30); } let (mut k, mut y) = (k0, y0); - while k < sieve_len { - tx.send((k, delta)).unwrap(); + while k < sieve.len() as i64 { + sieve[k as usize] ^= 1u16 << SieveOfAtkin::SHIFTS[delta as usize]; (k, y) = (k + y + 15, y + 30); } } } - fn algorithm_4_3(delta: i32, f: i32, g: i32, h: i32, sieve_len: i64, tx: &std::sync::mpsc::Sender<(i64, i32)>) { + fn algorithm_4_3(delta: i32, f: i32, g: i32, h: i32, sieve: &mut [u16]) { let (mut x, mut y0, mut k0) = (f as i64, g as i64, h as i64); loop { - while k0 >= sieve_len { + while k0 >= sieve.len() as i64 { if x <= y0 { return; } @@ -174,7 +171,7 @@ impl SieveOfAtkin { } let (mut k, mut y) = (k0, y0); while k >= 0 && y < x { - tx.send((k, delta)).unwrap(); + sieve[k as usize] ^= 1u16 << SieveOfAtkin::SHIFTS[delta as usize]; (k, y) = (k - y - 15, y + 30); } (k0, x) = (k0 + x + 5, x + 10);