Compare commits
No commits in common. "80f9cc855d3fe04d2b81945d682bcd417b975fca" and "c9db711008c4663043d03f8f5b1497f2b3e7ba1a" have entirely different histories.
80f9cc855d
...
c9db711008
115
Cargo.lock
generated
115
Cargo.lock
generated
@ -1,7 +1,5 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ansi_term"
|
name = "ansi_term"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
@ -22,24 +20,12 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "autocfg"
|
|
||||||
version = "1.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cfg-if"
|
|
||||||
version = "1.0.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "2.33.3"
|
version = "2.33.3"
|
||||||
@ -55,56 +41,6 @@ dependencies = [
|
|||||||
"vec_map",
|
"vec_map",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "crossbeam-channel"
|
|
||||||
version = "0.5.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e54ea8bc3fb1ee042f5aace6e3c6e025d3874866da222930f70ce62aceba0bfa"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"crossbeam-utils",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "crossbeam-deque"
|
|
||||||
version = "0.8.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"crossbeam-epoch",
|
|
||||||
"crossbeam-utils",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "crossbeam-epoch"
|
|
||||||
version = "0.9.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c00d6d2ea26e8b151d99093005cb442fb9a37aeaca582a03ec70946f49ab5ed9"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"crossbeam-utils",
|
|
||||||
"lazy_static",
|
|
||||||
"memoffset",
|
|
||||||
"scopeguard",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "crossbeam-utils"
|
|
||||||
version = "0.8.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b5e5bed1f1c269533fa816a0a5492b3545209a205ca1a54842be180eb63a16a6"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"lazy_static",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "either"
|
|
||||||
version = "1.6.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
version = "0.3.2"
|
version = "0.3.2"
|
||||||
@ -127,7 +63,6 @@ dependencies = [
|
|||||||
name = "indivisible"
|
name = "indivisible"
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rayon",
|
|
||||||
"structopt",
|
"structopt",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -143,25 +78,6 @@ version = "0.2.87"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "265d751d31d6780a3f956bb5b8022feba2d94eeee5a84ba64f4212eedca42213"
|
checksum = "265d751d31d6780a3f956bb5b8022feba2d94eeee5a84ba64f4212eedca42213"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "memoffset"
|
|
||||||
version = "0.6.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num_cpus"
|
|
||||||
version = "1.13.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
|
|
||||||
dependencies = [
|
|
||||||
"hermit-abi",
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro-error"
|
name = "proc-macro-error"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
@ -204,37 +120,6 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rayon"
|
|
||||||
version = "1.5.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
"crossbeam-deque",
|
|
||||||
"either",
|
|
||||||
"rayon-core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rayon-core"
|
|
||||||
version = "1.9.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e"
|
|
||||||
dependencies = [
|
|
||||||
"crossbeam-channel",
|
|
||||||
"crossbeam-deque",
|
|
||||||
"crossbeam-utils",
|
|
||||||
"lazy_static",
|
|
||||||
"num_cpus",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "scopeguard"
|
|
||||||
version = "1.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
|
@ -12,4 +12,3 @@ keywords = ["primes", "math"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
structopt = "0.3.13"
|
structopt = "0.3.13"
|
||||||
rayon = "1.5"
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
# Indivisible
|
===================
|
||||||
|
*** Indivisible ***
|
||||||
|
===================
|
||||||
Indivisible is an optimized prime number generator and tester written in Rust.
|
Indivisible is an optimized prime number generator and tester written in Rust.
|
||||||
|
|
||||||
## Build & Installation
|
# Build & Installation
|
||||||
|
----------------------
|
||||||
To build the project you will require the Rust compiler and build
|
To build the project you will require the Rust compiler and build
|
||||||
system, `cargo`. At which point you simply run `cargo build` in the root
|
system, `cargo`. At which point you simply run `cargo build` in the root
|
||||||
directory of the project. To create an optimized release build append
|
directory of the project. To create an optimized release build append
|
||||||
@ -14,8 +15,8 @@ the manpage documentation by running the `install` script. In a similar
|
|||||||
manner, you can run the `uninstall` script to remove the previously
|
manner, you can run the `uninstall` script to remove the previously
|
||||||
installed binary and documentation.
|
installed binary and documentation.
|
||||||
|
|
||||||
## Usage
|
# Usage
|
||||||
|
-------
|
||||||
The purpose of Indivisible is to find the nth prime and all the primes
|
The purpose of Indivisible is to find the nth prime and all the primes
|
||||||
before it. The basic usage is `indivisible <n>` where `n` is the ordinal
|
before it. The basic usage is `indivisible <n>` where `n` is the ordinal
|
||||||
of the prime you'd like to find. To display all primes before `n`, you
|
of the prime you'd like to find. To display all primes before `n`, you
|
||||||
@ -26,23 +27,22 @@ can also import prime numbers previously computed with the `--import` or
|
|||||||
`-i` option. To store already computed primes you are expected to use
|
`-i` option. To store already computed primes you are expected to use
|
||||||
piping like any UNIX user would expect. Here is an example:
|
piping like any UNIX user would expect. Here is an example:
|
||||||
|
|
||||||
```bash
|
# store first 100 primes in ./primes
|
||||||
# store first 100 primes in ./primes
|
indivisible -v 100 > ./primes
|
||||||
indivisible -v 100 > ./primes
|
# appends next 400 primes
|
||||||
# appends next 400 primes
|
indivisible -i ./primes -v 500 >> ./primes
|
||||||
indivisible -i ./primes -v 500 >> ./primes
|
# display the 600th prime
|
||||||
# display the 600th prime
|
indivisible -i ./primes 600
|
||||||
indivisible -i ./primes 600
|
|
||||||
```
|
|
||||||
|
|
||||||
## Legacy
|
# Legacy
|
||||||
|
--------
|
||||||
This project was originally written in C. It can be found in the
|
This project was originally written in C. It can be found on my GitLab
|
||||||
[indivisible-legacy repository](https://gitlab.com/naortega/Indivisible-legacy)
|
page.[1]
|
||||||
on my GitLab.
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
|
# License
|
||||||
|
---------
|
||||||
This project is licensed under the terms & conditions of the GNU General
|
This project is licensed under the terms & conditions of the GNU General
|
||||||
Public License version 3 or greater (see `LICENSE` file for more
|
Public License version 3 or greater (see `LICENSE` file for more
|
||||||
information).
|
information).
|
||||||
|
|
||||||
|
[1] https://gitlab.com/naortega/Indivisible-legacy
|
33
src/main.rs
33
src/main.rs
@ -30,12 +30,12 @@ struct Opt
|
|||||||
{
|
{
|
||||||
#[structopt(short, long, help = "Print all found primes")]
|
#[structopt(short, long, help = "Print all found primes")]
|
||||||
verbose:bool,
|
verbose:bool,
|
||||||
#[structopt(short, long, name = "FILE", help = "Import prime numbers from FILE")]
|
#[structopt(short, long, name="FILE", help = "Import prime numbers from FILE")]
|
||||||
import:Option<PathBuf>,
|
import:Option<PathBuf>,
|
||||||
#[structopt(short, long, help = "Test if n is prime instead of generation")]
|
#[structopt(short, long, help = "Test if n is prime instead of generation")]
|
||||||
test:bool,
|
test:bool,
|
||||||
#[structopt(help = "Ordinal of the prime to generate")]
|
#[structopt(help = "Ordinal of the prime to generate")]
|
||||||
n:u64,
|
n:usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main()
|
fn main()
|
||||||
@ -50,9 +50,12 @@ fn main()
|
|||||||
{
|
{
|
||||||
let in_file = File::open(opts.import.unwrap()).unwrap();
|
let in_file = File::open(opts.import.unwrap()).unwrap();
|
||||||
let reader = BufReader::new(in_file);
|
let reader = BufReader::new(in_file);
|
||||||
reader.lines().into_iter().for_each(|x| {
|
for line in reader.lines()
|
||||||
primes.push_back(x.unwrap().parse().unwrap());
|
{
|
||||||
});
|
let line = line.unwrap();
|
||||||
|
let aux:u64 = line.parse().unwrap();
|
||||||
|
primes.push_back(aux);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.test
|
if opts.test
|
||||||
@ -61,17 +64,17 @@ fn main()
|
|||||||
// if no primes were imported, test from beginning (2)
|
// if no primes were imported, test from beginning (2)
|
||||||
if primes.len() == 0
|
if primes.len() == 0
|
||||||
{
|
{
|
||||||
res = test::is_prime(n);
|
res = test::is_prime(n as u64);
|
||||||
}
|
}
|
||||||
// `n` should be in `primes` if the last prime is larger than `n`
|
// `n` should be in `primes` if the last prime is larger than `n`
|
||||||
else if primes.back().unwrap() >= &(n)
|
else if primes.back().unwrap() >= &(n as u64)
|
||||||
{
|
{
|
||||||
res = primes.contains(&(n));
|
res = primes.contains(&(n as u64));
|
||||||
}
|
}
|
||||||
// we can memory test `n` if the last prime is >= sqrt(n)
|
// we can memory test `n` if the last prime is >= sqrt(n)
|
||||||
else if primes.back().unwrap() >= &((n as f64).sqrt() as u64)
|
else if primes.back().unwrap() >= &((n as f64).sqrt() as u64)
|
||||||
{
|
{
|
||||||
res = test::is_prime_mem(n, &primes)
|
res = test::is_prime_mem(n as u64, &primes)
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* if we have less primes than sqrt(n) then we can test all those
|
* if we have less primes than sqrt(n) then we can test all those
|
||||||
@ -80,10 +83,10 @@ fn main()
|
|||||||
*/
|
*/
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
res = test::is_prime_mem(n, &primes);
|
res = test::is_prime_mem(n as u64, &primes);
|
||||||
if res
|
if res
|
||||||
{
|
{
|
||||||
res = test::is_prime_f(n, primes.back().unwrap() + 2);
|
res = test::is_prime_f(n as u64, primes.back().unwrap() + 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,9 +110,9 @@ fn main()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// if `primes` already contains the nth prime, print it
|
// if `primes` already contains the nth prime, print it
|
||||||
if primes.len() >= n as usize
|
if primes.len() >= n
|
||||||
{
|
{
|
||||||
println!("{}", primes.get((n as usize) - 1).unwrap());
|
println!("{}", primes.get(n-1).unwrap());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -134,7 +137,7 @@ fn main()
|
|||||||
candidate = *primes.back().unwrap() + 2;
|
candidate = *primes.back().unwrap() + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
while primes.len() < n as usize
|
while primes.len() < n
|
||||||
{
|
{
|
||||||
if test::is_prime_mem(candidate, &primes)
|
if test::is_prime_mem(candidate, &primes)
|
||||||
{
|
{
|
||||||
@ -150,7 +153,7 @@ fn main()
|
|||||||
|
|
||||||
if !opts.verbose
|
if !opts.verbose
|
||||||
{
|
{
|
||||||
println!("{}", primes.get((n as usize) - 1).unwrap());
|
println!("{}", primes.get(n-1).unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
29
src/test.rs
29
src/test.rs
@ -17,18 +17,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use rayon::prelude::*;
|
|
||||||
|
|
||||||
pub fn is_prime_f(n:u64, b:u64) -> bool
|
pub fn is_prime_f(n:u64, b:u64) -> bool
|
||||||
{
|
{
|
||||||
assert_ne!(b, 0);
|
assert_ne!(b, 0);
|
||||||
assert_ne!(b, 1);
|
assert_ne!(b, 1);
|
||||||
|
|
||||||
if n == 1
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut start = b;
|
let mut start = b;
|
||||||
if start == 2
|
if start == 2
|
||||||
{
|
{
|
||||||
@ -48,9 +42,14 @@ pub fn is_prime_f(n:u64, b:u64) -> bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
let limit = (n as f64).sqrt() as u64 + 1;
|
let limit = (n as f64).sqrt() as u64 + 1;
|
||||||
let composite = (start..limit).step_by(2).collect::<Vec<u64>>()
|
for i in (start..limit).step_by(2)
|
||||||
.par_iter().any(|x| n % x == 0);
|
{
|
||||||
return !composite;
|
if n % i == 0
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_prime(n:u64) -> bool
|
pub fn is_prime(n:u64) -> bool
|
||||||
@ -61,8 +60,12 @@ pub fn is_prime(n:u64) -> bool
|
|||||||
pub fn is_prime_mem(n:u64, primes:&VecDeque<u64>) -> bool
|
pub fn is_prime_mem(n:u64, primes:&VecDeque<u64>) -> bool
|
||||||
{
|
{
|
||||||
let limit = (n as f64).sqrt() as u64;
|
let limit = (n as f64).sqrt() as u64;
|
||||||
let pp = primes.partition_point(|x| *x < limit);
|
for i in primes.iter().take_while(|x| **x <= limit)
|
||||||
//let composite = primes.par_iter().take(pp+1).any(|x| n % *x == 0);
|
{
|
||||||
let composite = primes.iter().take(pp+1).any(|x| n % *x == 0);
|
if n % *i == 0
|
||||||
return !composite;
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user