Sieve
1. Readme
素数筛
使用 Eratosthenes 的 Sieve 查找从 2 到给定数字的所有素数.
这是一种简单且历史悠久的筛法,用来找出一定范围内所有的素数。
所使用的原理是从 2 开始,将每个素数的各个倍数,标记成合数。一个素数的各个倍数,是一个差为此素数本身的等差数列。此为这个筛法和试除法不同的关键之处,后者是以素数来测试每个待测数能否被整除。
埃拉托斯特尼筛法是列出所有小素数最有效的方法之一,其名字来自于古希腊数学家埃拉托斯特尼,并且被描述在另一位古希腊数学家尼科马库斯所著的《算术入门》中。
维基百科文章有一个有用的图解解释算法:
请注意,这是一个非常具体的算法,并且测试不会检查您是否实现了算法,只要您已经提出了正确的素数列表.https://zh.wikipedia.org/wiki/埃拉托斯特尼筛法
一个好的第一个测试是,检查你不使用除法或余数运算(div, /, mod or % 具体语言所具有的)
资源
维基百科的 素数 筛https://zh.wikipedia.org/wiki/埃拉托斯特尼筛法
2. 开始你的表演
pub fn primes_up_to(upper_bound: u64) -> Vec<u64> { unimplemented!("Construct a vector of all primes up to {}", upper_bound); }
3. 测试代码查看
# #![allow(unused_variables)] #fn main() { #[test] fn limit_lower_than_the_first_prime() { assert_eq!(primes_up_to(1), []); } #[test] //#[ignore] fn limit_is_the_first_prime() { assert_eq!(primes_up_to(2), [2]); } #[test] //#[ignore] fn primes_up_to_10() { assert_eq!(primes_up_to(10), [2, 3, 5, 7]); } #[test] //#[ignore] fn limit_is_prime() { assert_eq!(primes_up_to(13), [2, 3, 5, 7, 11, 13]); } #[test] //#[ignore] fn limit_of_1000() { let expected = vec![ 2, 3, 5, 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, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, ]; assert_eq!(primes_up_to(1000), expected); } #}
4. 答案
# #![allow(unused_variables)] #fn main() { pub fn primes_up_to(limit: i32) -> Vec<i32> { let mut integers = (1..limit).map(|x| x + 1).collect::<Vec<i32>>(); let mut p = Some(2); while let Some(y) = p { integers.retain(|&x| (x == y) || (x % y != 0)); p = integers.clone().into_iter().find(|x| *x > y); } integers } #}