Compare commits
	
		
			10 Commits
		
	
	
		
			c9db711008
			...
			80f9cc855d
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 80f9cc855d | |||
| f45932e188 | |||
| 374bc02b50 | |||
| df7017518e | |||
| a2dfd6a6ca | |||
| 5c8c7baa75 | |||
| b682ad9e9b | |||
| caad128ad2 | |||
| 7c2a5e7250 | |||
| d2f59a6b21 | 
							
								
								
									
										115
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										115
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							@@ -1,5 +1,7 @@
 | 
			
		||||
# This file is automatically @generated by Cargo.
 | 
			
		||||
# It is not intended for manual editing.
 | 
			
		||||
version = 3
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "ansi_term"
 | 
			
		||||
version = "0.11.0"
 | 
			
		||||
@@ -20,12 +22,24 @@ dependencies = [
 | 
			
		||||
 "winapi",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "autocfg"
 | 
			
		||||
version = "1.1.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "bitflags"
 | 
			
		||||
version = "1.2.1"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "cfg-if"
 | 
			
		||||
version = "1.0.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "clap"
 | 
			
		||||
version = "2.33.3"
 | 
			
		||||
@@ -41,6 +55,56 @@ dependencies = [
 | 
			
		||||
 "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]]
 | 
			
		||||
name = "heck"
 | 
			
		||||
version = "0.3.2"
 | 
			
		||||
@@ -63,6 +127,7 @@ dependencies = [
 | 
			
		||||
name = "indivisible"
 | 
			
		||||
version = "2.0.0"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "rayon",
 | 
			
		||||
 "structopt",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
@@ -78,6 +143,25 @@ version = "0.2.87"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
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]]
 | 
			
		||||
name = "proc-macro-error"
 | 
			
		||||
version = "1.0.4"
 | 
			
		||||
@@ -120,6 +204,37 @@ dependencies = [
 | 
			
		||||
 "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]]
 | 
			
		||||
name = "strsim"
 | 
			
		||||
version = "0.8.0"
 | 
			
		||||
 
 | 
			
		||||
@@ -12,3 +12,4 @@ keywords = ["primes", "math"]
 | 
			
		||||
 | 
			
		||||
[dependencies]
 | 
			
		||||
structopt = "0.3.13"
 | 
			
		||||
rayon = "1.5"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,9 @@
 | 
			
		||||
===================
 | 
			
		||||
*** Indivisible ***
 | 
			
		||||
===================
 | 
			
		||||
# Indivisible
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
system, `cargo`. At which point you simply run `cargo build` in the root
 | 
			
		||||
directory of the project. To create an optimized release build append
 | 
			
		||||
@@ -15,8 +14,8 @@ the manpage documentation by running the `install` script. In a similar
 | 
			
		||||
manner, you can run the `uninstall` script to remove the previously
 | 
			
		||||
installed binary and documentation.
 | 
			
		||||
 | 
			
		||||
# Usage
 | 
			
		||||
-------
 | 
			
		||||
## Usage
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
of the prime you'd like to find. To display all primes before `n`, you
 | 
			
		||||
@@ -27,22 +26,23 @@ can also import prime numbers previously computed with the `--import` or
 | 
			
		||||
`-i` option. To store already computed primes you are expected to use
 | 
			
		||||
piping like any UNIX user would expect. Here is an example:
 | 
			
		||||
 | 
			
		||||
  # store first 100 primes in ./primes
 | 
			
		||||
  indivisible -v 100 > ./primes
 | 
			
		||||
  # appends next 400 primes
 | 
			
		||||
  indivisible -i ./primes -v 500 >> ./primes
 | 
			
		||||
  # display the 600th prime
 | 
			
		||||
  indivisible -i ./primes 600
 | 
			
		||||
```bash
 | 
			
		||||
# store first 100 primes in ./primes
 | 
			
		||||
indivisible -v 100 > ./primes
 | 
			
		||||
# appends next 400 primes
 | 
			
		||||
indivisible -i ./primes -v 500 >> ./primes
 | 
			
		||||
# display the 600th prime
 | 
			
		||||
indivisible -i ./primes 600
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
# Legacy
 | 
			
		||||
--------
 | 
			
		||||
This project was originally written in C. It can be found on my GitLab
 | 
			
		||||
page.[1]
 | 
			
		||||
## Legacy
 | 
			
		||||
 | 
			
		||||
This project was originally written in C. It can be found in the
 | 
			
		||||
[indivisible-legacy repository](https://gitlab.com/naortega/Indivisible-legacy)
 | 
			
		||||
on my GitLab.
 | 
			
		||||
 | 
			
		||||
## License
 | 
			
		||||
 | 
			
		||||
# License
 | 
			
		||||
---------
 | 
			
		||||
This project is licensed under the terms & conditions of the GNU General
 | 
			
		||||
Public License version 3 or greater (see `LICENSE` file for more
 | 
			
		||||
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")]
 | 
			
		||||
	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>,
 | 
			
		||||
	#[structopt(short, long, help = "Test if n is prime instead of generation")]
 | 
			
		||||
	test:bool,
 | 
			
		||||
	#[structopt(help = "Ordinal of the prime to generate")]
 | 
			
		||||
	n:usize,
 | 
			
		||||
	n:u64,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn main()
 | 
			
		||||
@@ -50,12 +50,9 @@ fn main()
 | 
			
		||||
	{
 | 
			
		||||
		let in_file = File::open(opts.import.unwrap()).unwrap();
 | 
			
		||||
		let reader = BufReader::new(in_file);
 | 
			
		||||
		for line in reader.lines()
 | 
			
		||||
		{
 | 
			
		||||
			let line = line.unwrap();
 | 
			
		||||
			let aux:u64 = line.parse().unwrap();
 | 
			
		||||
			primes.push_back(aux);
 | 
			
		||||
		}
 | 
			
		||||
		reader.lines().into_iter().for_each(|x| {
 | 
			
		||||
			primes.push_back(x.unwrap().parse().unwrap());
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if opts.test
 | 
			
		||||
@@ -64,17 +61,17 @@ fn main()
 | 
			
		||||
		// if no primes were imported, test from beginning (2)
 | 
			
		||||
		if primes.len() == 0
 | 
			
		||||
		{
 | 
			
		||||
			res = test::is_prime(n as u64);
 | 
			
		||||
			res = test::is_prime(n);
 | 
			
		||||
		}
 | 
			
		||||
		// `n` should be in `primes` if the last prime is larger than `n`
 | 
			
		||||
		else if primes.back().unwrap() >= &(n as u64)
 | 
			
		||||
		else if primes.back().unwrap() >= &(n)
 | 
			
		||||
		{
 | 
			
		||||
			res = primes.contains(&(n as u64));
 | 
			
		||||
			res = primes.contains(&(n));
 | 
			
		||||
		}
 | 
			
		||||
		// we can memory test `n` if the last prime is >= sqrt(n)
 | 
			
		||||
		else if primes.back().unwrap() >= &((n as f64).sqrt() as u64)
 | 
			
		||||
		{
 | 
			
		||||
			res = test::is_prime_mem(n as u64, &primes)
 | 
			
		||||
			res = test::is_prime_mem(n, &primes)
 | 
			
		||||
		}
 | 
			
		||||
		/*
 | 
			
		||||
		 * if we have less primes than sqrt(n) then we can test all those
 | 
			
		||||
@@ -83,10 +80,10 @@ fn main()
 | 
			
		||||
		 */
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			res = test::is_prime_mem(n as u64, &primes);
 | 
			
		||||
			res = test::is_prime_mem(n, &primes);
 | 
			
		||||
			if res
 | 
			
		||||
			{
 | 
			
		||||
				res = test::is_prime_f(n as u64, primes.back().unwrap() + 2);
 | 
			
		||||
				res = test::is_prime_f(n, primes.back().unwrap() + 2);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -110,9 +107,9 @@ fn main()
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		// if `primes` already contains the nth prime, print it
 | 
			
		||||
		if primes.len() >= n
 | 
			
		||||
		if primes.len() >= n as usize
 | 
			
		||||
		{
 | 
			
		||||
			println!("{}", primes.get(n-1).unwrap());
 | 
			
		||||
			println!("{}", primes.get((n as usize) - 1).unwrap());
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
@@ -137,7 +134,7 @@ fn main()
 | 
			
		||||
				candidate = *primes.back().unwrap() + 2;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			while primes.len() < n
 | 
			
		||||
			while primes.len() < n as usize
 | 
			
		||||
			{
 | 
			
		||||
				if test::is_prime_mem(candidate, &primes)
 | 
			
		||||
				{
 | 
			
		||||
@@ -153,7 +150,7 @@ fn main()
 | 
			
		||||
 | 
			
		||||
			if !opts.verbose
 | 
			
		||||
			{
 | 
			
		||||
				println!("{}", primes.get(n-1).unwrap());
 | 
			
		||||
				println!("{}", primes.get((n as usize) - 1).unwrap());
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										29
									
								
								src/test.rs
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								src/test.rs
									
									
									
									
									
								
							@@ -17,12 +17,18 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
use std::collections::VecDeque;
 | 
			
		||||
use rayon::prelude::*;
 | 
			
		||||
 | 
			
		||||
pub fn is_prime_f(n:u64, b:u64) -> bool
 | 
			
		||||
{
 | 
			
		||||
	assert_ne!(b, 0);
 | 
			
		||||
	assert_ne!(b, 1);
 | 
			
		||||
 | 
			
		||||
	if n == 1
 | 
			
		||||
	{
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	let mut start = b;
 | 
			
		||||
	if start == 2
 | 
			
		||||
	{
 | 
			
		||||
@@ -42,14 +48,9 @@ pub fn is_prime_f(n:u64, b:u64) -> bool
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	let limit = (n as f64).sqrt() as u64 + 1;
 | 
			
		||||
	for i in (start..limit).step_by(2)
 | 
			
		||||
	{
 | 
			
		||||
		if n % i == 0
 | 
			
		||||
		{
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return true;
 | 
			
		||||
	let composite = (start..limit).step_by(2).collect::<Vec<u64>>()
 | 
			
		||||
		.par_iter().any(|x| n % x == 0);
 | 
			
		||||
	return !composite;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn is_prime(n:u64) -> bool
 | 
			
		||||
@@ -60,12 +61,8 @@ pub fn is_prime(n:u64) -> bool
 | 
			
		||||
pub fn is_prime_mem(n:u64, primes:&VecDeque<u64>) -> bool
 | 
			
		||||
{
 | 
			
		||||
	let limit = (n as f64).sqrt() as u64;
 | 
			
		||||
	for i in primes.iter().take_while(|x| **x <= limit)
 | 
			
		||||
	{
 | 
			
		||||
		if n % *i == 0
 | 
			
		||||
		{
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return true;
 | 
			
		||||
	let pp = primes.partition_point(|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);
 | 
			
		||||
	return !composite;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user