Compare commits

...

9 Commits

Author SHA1 Message Date
084aa14026 Simplify README.md 2025-12-10 15:06:27 +01:00
966574dd1f Change default sieve size to 10485760.
I don't know why yet, but this seems to be the near optimal sieve size
when testing with the benchmarking script. It's equal to `1024^2 * 10`.
2025-12-10 14:59:52 +01:00
41bc18a17c Change test to 1,000,000,000 primes. 2025-12-10 14:59:33 +01:00
5dde94ae8c Add custom sieve and trials arguments to benchmark script. 2025-12-10 14:45:59 +01:00
be3fd52cfa Improve help information. 2025-12-10 14:21:50 +01:00
0b391ed590 Allow for providing a custom sieve size. 2025-12-10 13:59:53 +01:00
f5b971e35f Add comments to test.sh for better navigation. 2025-12-10 13:52:46 +01:00
abfb1aee89 Fix test 1. 2025-12-10 13:52:12 +01:00
4b3bf0cfac Fix importing primes. 2025-12-10 13:29:02 +01:00
5 changed files with 63 additions and 39 deletions

View File

@@ -1,38 +1,29 @@
# Indivisible
Indivisible is an optimized prime number generator and tester written in Rust.
Indivisible is an optimized prime number generator and tester.
## 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
the `--release` flag to the previous command.
Build a binary release using the following command:
Once a release build has been compiled, you may install Indivisible and
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.
```console
$ cargo build -r
```
## 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
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
can run verbose mode by using the `--verbose` or simply `-v` option.
```console
$ PREFIX="~/.local" ./install
```
Since Indivisible generates primes using previously computed primes, you
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:
Additionally there is an `uninstall` script available. If you have used a custom
`PREFIX` this must also be specified to uninstall in the same manner. To see
where you've installed it you can always use the following command:
```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
```console
$ which indivisible
```
## Legacy

View File

@@ -1,9 +1,10 @@
#!/bin/bash
BIN="./target/release/indivisible"
EXE="./target/release/indivisible"
OPTIONS=()
TRIALS=20
if ! [ -f "$BIN" ]
if ! [ -f "$EXE" ]
then
>&2 echo "Release build not available. Please run 'cargo build -r'."
exit 1
@@ -15,11 +16,27 @@ then
exit 1
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"
for _ in $(seq "$TRIALS")
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")
done

View File

@@ -6,7 +6,9 @@ indivisible \- prime number generator and tester
[\fIOPTIONS\fR] <\fIn\fR>
.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"
.TP
@@ -19,6 +21,9 @@ Import prime numbers from \fIFILE\fR
\fB\-t\fR, \fB\-\-test\fR
Test if n is a prime instead of generation
.TP
\fB\-s\fR, \fB\-\-sieve\fR <\fISIZE\fR>
Set a custom sieve size
.TP
\fB\-v\fR, \fB\-\-verbose\fR
Print all found primes
.TP

View File

@@ -35,12 +35,12 @@ struct Opt {
test:bool,
#[structopt(help = "Max of the prime to generate or number to test for primality")]
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")]
//jobs:u64,
}
const SEGMENT_SIZE:usize = 0x100000000;
fn main() {
let opts = Opt::from_args();
let mut prime_list = Vec::new();
@@ -49,7 +49,12 @@ fn main() {
let in_file = File::open(opts.import.unwrap()).unwrap();
let reader = BufReader::new(in_file);
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() {
2
} else {
*prime_list.last().unwrap() as usize
(*prime_list.last().unwrap() + 1) as usize
};
while start < opts.num {
let end = if start + SEGMENT_SIZE < opts.num {
start + SEGMENT_SIZE
let end = if start + opts.sieve < opts.num {
start + opts.sieve
} else {
opts.num + 1
};
@@ -78,7 +83,7 @@ fn main() {
}
prime_list.append(&mut new_primes);
start += SEGMENT_SIZE;
start += opts.sieve;
}
if opts.test {

10
test.sh
View File

@@ -17,9 +17,12 @@ fi
tests=0
passed=0
## TEST 1
((tests++))
echo -n "${tests}: Find 5th prime number..."
if [[ $("$BINARY" 5) == 11 ]]
echo -n "${tests}: Find all prime numbers before 70..."
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
echo " pass"
((passed++))
@@ -27,6 +30,7 @@ else
echo " FAIL"
fi
## TEST 2
((tests++))
echo -n "${tests}: 11 is prime..."
if "$BINARY" -t 11
@@ -37,6 +41,7 @@ else
echo " FAIL"
fi
## TEST 3
((tests++))
echo -n "${tests}: 9 is not prime..."
if ! "$BINARY" -t 9
@@ -47,4 +52,5 @@ else
echo " FAIL"
fi
## RESULTS
echo "Results: $passed/$tests"