1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
//! Generate the nth prime number. Note: limit of n index stands at [1, 1_000_000).
//! # Algorithm
//! primenumbe-rs crate's algorithm is inspired by the the optimized version of the Sieve of Eratosthenes.
//!
/// '''no_run
/// use primenumbe_rs::Primenumber;
/// '''
/// # Example
///
/// '''no_run
///
/// let n: u64 = 100;
/// let result = Primenumber::nthprime(n);
/// assert_eq!(result, 541u64);
/// '''
///

pub struct Primenumber<T> {
    num: T,
}

impl<T: Into<u64> + Copy> Primenumber<T> {
    pub fn nthprime(n: T) -> u64 {
        get_nth_prime(&Primenumber { num: n })
    }
}

pub fn get_nth_prime<T: Into<u64> + Copy>(nth: &Primenumber<T>) -> u64 {
    let mut total_prime: u64 = 0;
    let mut size_factor: u64 = 2;

    let mut s: u64 = nth.num.into() * size_factor;
    let mut primes: Vec<u64> = Vec::new();

    let n: u64 = nth.num.into();

    while total_prime < n {
        primes = get_primes(s).to_vec();

        total_prime = primes[2..].iter().sum();
        size_factor += 1;
        s = n * size_factor;
    }

    count_prime(primes, n).unwrap()
}

fn get_primes(s: u64) -> Vec<u64> {
    let mut v: Vec<u64> = vec![1; s as usize];

    for index in 2..s {
        if v[index as usize] == 1 {
            for j in index..s {
                if index * j < s {
                    v[(index * j) as usize] = 0;
                } else {
                    break;
                }
            }
        }
    }
    v
}

fn count_prime(primes: Vec<u64>, n: u64) -> Option<u64> {
    let mut counter: u64 = 0;
    for i in 2..primes.len() {
        counter += primes[i];
        if counter == n {
            return Some(i as u64);
        }
    }
    None
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn it_works() {
        let n: u16 = 100;
        let result = Primenumber::nthprime(n);
        assert_eq!(result, 541u64);
    }
}