Compare commits
9 Commits
ba3478e6ce
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 084aa14026 | |||
| 966574dd1f | |||
| 41bc18a17c | |||
| 5dde94ae8c | |||
| be3fd52cfa | |||
| 0b391ed590 | |||
| f5b971e35f | |||
| abfb1aee89 | |||
| 4b3bf0cfac |
41
README.md
41
README.md
@@ -1,38 +1,29 @@
|
|||||||
# Indivisible
|
# Indivisible
|
||||||
|
|
||||||
Indivisible is an optimized prime number generator and tester written in Rust.
|
Indivisible is an optimized prime number generator and tester.
|
||||||
|
|
||||||
## Build & Installation
|
## Build & Installation
|
||||||
|
|
||||||
To build the project you will require the Rust compiler and build
|
Build a binary release using the following command:
|
||||||
system, `cargo`. At which point you simply run `cargo build` in the root
|
|
||||||
directory of the project. To create an optimized release build append
|
|
||||||
the `--release` flag to the previous command.
|
|
||||||
|
|
||||||
Once a release build has been compiled, you may install Indivisible and
|
```console
|
||||||
the manpage documentation by running the `install` script. In a similar
|
$ cargo build -r
|
||||||
manner, you can run the `uninstall` script to remove the previously
|
```
|
||||||
installed binary and documentation.
|
|
||||||
|
|
||||||
## Usage
|
Once compiled, you can install it using the `install` script. By default this
|
||||||
|
will install to `/usr/local/{bin,share}`, but you can optionally change the
|
||||||
|
`PREFIX` used as follows:
|
||||||
|
|
||||||
The purpose of Indivisible is to find the nth prime and all the primes
|
```console
|
||||||
before it. The basic usage is `indivisible <n>` where `n` is the ordinal
|
$ PREFIX="~/.local" ./install
|
||||||
of the prime you'd like to find. To display all primes before `n`, you
|
```
|
||||||
can run verbose mode by using the `--verbose` or simply `-v` option.
|
|
||||||
|
|
||||||
Since Indivisible generates primes using previously computed primes, you
|
Additionally there is an `uninstall` script available. If you have used a custom
|
||||||
can also import prime numbers previously computed with the `--import` or
|
`PREFIX` this must also be specified to uninstall in the same manner. To see
|
||||||
`-i` option. To store already computed primes you are expected to use
|
where you've installed it you can always use the following command:
|
||||||
piping like any UNIX user would expect. Here is an example:
|
|
||||||
|
|
||||||
```bash
|
```console
|
||||||
# store first 100 primes in ./primes
|
$ which indivisible
|
||||||
indivisible -v 100 > ./primes
|
|
||||||
# appends next 400 primes
|
|
||||||
indivisible -i ./primes -v 500 >> ./primes
|
|
||||||
# display the 600th prime
|
|
||||||
indivisible -i ./primes 600
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Legacy
|
## Legacy
|
||||||
|
|||||||
25
benchmark.sh
25
benchmark.sh
@@ -1,9 +1,10 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
BIN="./target/release/indivisible"
|
EXE="./target/release/indivisible"
|
||||||
|
OPTIONS=()
|
||||||
TRIALS=20
|
TRIALS=20
|
||||||
|
|
||||||
if ! [ -f "$BIN" ]
|
if ! [ -f "$EXE" ]
|
||||||
then
|
then
|
||||||
>&2 echo "Release build not available. Please run 'cargo build -r'."
|
>&2 echo "Release build not available. Please run 'cargo build -r'."
|
||||||
exit 1
|
exit 1
|
||||||
@@ -15,11 +16,27 @@ then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Calculating primes up to 100,000,000"
|
while getopts "t:s:" opt
|
||||||
|
do
|
||||||
|
case "$opt" in
|
||||||
|
s)
|
||||||
|
OPTIONS=("${OPTIONS[@]}" -s "$OPTARG")
|
||||||
|
;;
|
||||||
|
t)
|
||||||
|
TRIALS="$OPTARG"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
>&2 echo "Uknown option $opt"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Calculating primes up to 1,000,000,000"
|
||||||
TOTAL="0"
|
TOTAL="0"
|
||||||
for _ in $(seq "$TRIALS")
|
for _ in $(seq "$TRIALS")
|
||||||
do
|
do
|
||||||
TIME=$(command time -f "%e" "$BIN" 100000000 2>&1 >/dev/null)
|
TIME=$(command time -f "%e" "$EXE" "${OPTIONS[@]}" 1000000000 2>&1 >/dev/null)
|
||||||
TOTAL=$(calc "$TOTAL + $TIME")
|
TOTAL=$(calc "$TOTAL + $TIME")
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ indivisible \- prime number generator and tester
|
|||||||
[\fIOPTIONS\fR] <\fIn\fR>
|
[\fIOPTIONS\fR] <\fIn\fR>
|
||||||
|
|
||||||
.SH "DESCRIPTION"
|
.SH "DESCRIPTION"
|
||||||
Indivisible is a program for working with prime numbers. Its default behaviour will attempt to find the \fInth\fR prime.
|
Indivisible is a program for working with prime numbers. It can either generate
|
||||||
|
primes up to a limit \fIn\fR or test to see if \fIn\fR is a prime. It makes use
|
||||||
|
of a segmented sieve of Eratosthenes.
|
||||||
|
|
||||||
.SH "OPTIONS"
|
.SH "OPTIONS"
|
||||||
.TP
|
.TP
|
||||||
@@ -19,6 +21,9 @@ Import prime numbers from \fIFILE\fR
|
|||||||
\fB\-t\fR, \fB\-\-test\fR
|
\fB\-t\fR, \fB\-\-test\fR
|
||||||
Test if n is a prime instead of generation
|
Test if n is a prime instead of generation
|
||||||
.TP
|
.TP
|
||||||
|
\fB\-s\fR, \fB\-\-sieve\fR <\fISIZE\fR>
|
||||||
|
Set a custom sieve size
|
||||||
|
.TP
|
||||||
\fB\-v\fR, \fB\-\-verbose\fR
|
\fB\-v\fR, \fB\-\-verbose\fR
|
||||||
Print all found primes
|
Print all found primes
|
||||||
.TP
|
.TP
|
||||||
|
|||||||
19
src/main.rs
19
src/main.rs
@@ -35,12 +35,12 @@ struct Opt {
|
|||||||
test:bool,
|
test:bool,
|
||||||
#[structopt(help = "Max of the prime to generate or number to test for primality")]
|
#[structopt(help = "Max of the prime to generate or number to test for primality")]
|
||||||
num:usize,
|
num:usize,
|
||||||
|
#[structopt(short, long, name = "SIZE", default_value = "10485760", help = "Set a custom sieve size")]
|
||||||
|
sieve:usize,
|
||||||
//#[structopt(short, long, name = "n", default_value = "1", help = "Number of threads to spawn")]
|
//#[structopt(short, long, name = "n", default_value = "1", help = "Number of threads to spawn")]
|
||||||
//jobs:u64,
|
//jobs:u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
const SEGMENT_SIZE:usize = 0x100000000;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let opts = Opt::from_args();
|
let opts = Opt::from_args();
|
||||||
let mut prime_list = Vec::new();
|
let mut prime_list = Vec::new();
|
||||||
@@ -49,7 +49,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);
|
||||||
for p in reader.lines().into_iter() {
|
for p in reader.lines().into_iter() {
|
||||||
prime_list.push(p.unwrap().parse().unwrap());
|
let prime:u64 = p.unwrap().parse().unwrap();
|
||||||
|
if (prime as usize) > opts.num {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
prime_list.push(prime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,11 +66,11 @@ fn main() {
|
|||||||
let mut start:usize = if prime_list.is_empty() {
|
let mut start:usize = if prime_list.is_empty() {
|
||||||
2
|
2
|
||||||
} else {
|
} else {
|
||||||
*prime_list.last().unwrap() as usize
|
(*prime_list.last().unwrap() + 1) as usize
|
||||||
};
|
};
|
||||||
while start < opts.num {
|
while start < opts.num {
|
||||||
let end = if start + SEGMENT_SIZE < opts.num {
|
let end = if start + opts.sieve < opts.num {
|
||||||
start + SEGMENT_SIZE
|
start + opts.sieve
|
||||||
} else {
|
} else {
|
||||||
opts.num + 1
|
opts.num + 1
|
||||||
};
|
};
|
||||||
@@ -78,7 +83,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
prime_list.append(&mut new_primes);
|
prime_list.append(&mut new_primes);
|
||||||
|
|
||||||
start += SEGMENT_SIZE;
|
start += opts.sieve;
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.test {
|
if opts.test {
|
||||||
|
|||||||
10
test.sh
10
test.sh
@@ -17,9 +17,12 @@ fi
|
|||||||
tests=0
|
tests=0
|
||||||
passed=0
|
passed=0
|
||||||
|
|
||||||
|
## TEST 1
|
||||||
((tests++))
|
((tests++))
|
||||||
echo -n "${tests}: Find 5th prime number..."
|
echo -n "${tests}: Find all prime numbers before 70..."
|
||||||
if [[ $("$BINARY" 5) == 11 ]]
|
expect="2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 "
|
||||||
|
|
||||||
|
if [ "$("$BINARY" -v 70 | tr '\n' ' ')" = "$expect" ]
|
||||||
then
|
then
|
||||||
echo " pass"
|
echo " pass"
|
||||||
((passed++))
|
((passed++))
|
||||||
@@ -27,6 +30,7 @@ else
|
|||||||
echo " FAIL"
|
echo " FAIL"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
## TEST 2
|
||||||
((tests++))
|
((tests++))
|
||||||
echo -n "${tests}: 11 is prime..."
|
echo -n "${tests}: 11 is prime..."
|
||||||
if "$BINARY" -t 11
|
if "$BINARY" -t 11
|
||||||
@@ -37,6 +41,7 @@ else
|
|||||||
echo " FAIL"
|
echo " FAIL"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
## TEST 3
|
||||||
((tests++))
|
((tests++))
|
||||||
echo -n "${tests}: 9 is not prime..."
|
echo -n "${tests}: 9 is not prime..."
|
||||||
if ! "$BINARY" -t 9
|
if ! "$BINARY" -t 9
|
||||||
@@ -47,4 +52,5 @@ else
|
|||||||
echo " FAIL"
|
echo " FAIL"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
## RESULTS
|
||||||
echo "Results: $passed/$tests"
|
echo "Results: $passed/$tests"
|
||||||
|
|||||||
Reference in New Issue
Block a user