Here’s the code without global **pcnt** and **primes**.

```
// Global variables
static modpg: i32 = 30;
static rescnt: i32 = 8;
static residues: [i32; 8] = [7, 11,13, 17, 19, 23, 29, 31];
static pos: [i32; 30] = [0,0,0,0,0,0,0,0,0,1,0,2,0,0,0,3,0,4,0,0,0,5,0,0,0,0,0,6,0,7];
fn sozpg(val: i32) -> Vec<i32> {
// Compute the list of primes r1..sqrt(input_num), and store in global
// 'primes' array, and store their count in global var 'pcnt'.
// Any algorithm (fast|small) is usable. Here the SoZ for the PG is used.
let md = modpg; // PG's modulus value
let rscnt = rescnt; // PG's residue count
let res = residues; // PG's residues list
let num = (val - 1) | 1; // if val even then subtract 1
let mut k = num / md; // compute its residue group value
let mut modk = md * k; // compute the resgroup base value
let mut r = 0i32; // from 1st residue in num's resgroup
while num >= modk + res[r as usize] { r += 1 } // find last pc val|position <= num
let maxpcs = k * rscnt + r; // max number of prime candidates <= num
let mut prms: Vec<bool> = Vec::with_capacity(maxpcs as usize); // pcs array, set False
prms = vec![false; maxpcs as usize];
let sqrtN = (num as f64).sqrt() as i32; // compute integer sqrt of input num
modk = 0; r = -1; k = 0; // initialize sieve parameters
// mark the multiples of the primes r1..sqrtN in 'prms'
for i in 0..maxpcs { // from list of pc positions in prms
r += 1; if r == rscnt { r = 0; modk += md; k += 1 }
if prms[i as usize] { continue }// if pc not prime go to next location
let prm_r = res[r as usize]; // if prime save its residue value
let prime = modk + prm_r; // numerate the prime value
if prime > sqrtN { break } // we're finished when it's > sqrtN
let prmstep = prime * rscnt; // prime's stepsize to mark its mults
for ri in res.iter() { // mark prime's multiples in prms
let prod = prm_r * ri - 2; // compute cross-product for r|ri pair
// compute resgroup val of 1st prime multiple for each restrack
// starting there, mark all prime multiples on restrack upto end of prms
let mut prm_mult = (k * (prime + ri) + prod/md) * rscnt + pos[(prod % md) as usize];
while prm_mult < maxpcs { prms[prm_mult as usize] = true; prm_mult += prmstep }
}
}
// prms now contains the nonprime positions for the prime candidates r1..N
// extract primes into global var 'primes' and count into global var 'pcnt'
let mut primes = Vec::new(); // create empty dynamic array for primes
modk = 0; r = -1; // initialize loop parameters
for &prm in prms.iter() { // numerate|store primes from pcs list
r += 1; if r == rscnt { r = 0; modk += md }
if !prm { primes.push(modk + res[r as usize]) }// put prime in global 'primes' list
}
primes
}
fn main() {
println!("{:?}", sozpg(541) );
println!("{}", sozpg(541).len() );
}
```

And output.

```
➜ time ./sozpg
[7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541]
97
./sozpg 0.00s user 0.00s system 82% cpu 0.001 total
```