aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAria Shrimpton <me@aria.rip>2024-01-23 11:54:47 +0000
committerAria Shrimpton <me@aria.rip>2024-01-23 11:54:47 +0000
commita8967d7d399b2324d5a9380d933d038e9159bb6b (patch)
tree65cc745b014ff4d44e40960ef3e563f90824c0f5
parentc3dc0f5463ec25353e79225add5c536da6fa2b4d (diff)
add prime sieve test
-rw-r--r--src/tests/Cargo.toml1
-rw-r--r--src/tests/prime_sieve/Cargo.toml16
-rw-r--r--src/tests/prime_sieve/benches/main.rs13
-rw-r--r--src/tests/prime_sieve/src/lib.rs55
-rw-r--r--src/tests/prime_sieve/src/types.pr.rs13
5 files changed, 98 insertions, 0 deletions
diff --git a/src/tests/Cargo.toml b/src/tests/Cargo.toml
index b40694f..120e0cd 100644
--- a/src/tests/Cargo.toml
+++ b/src/tests/Cargo.toml
@@ -2,6 +2,7 @@
resolver = "2"
members = [
"example_stack",
+ "prime_sieve"
]
[workspace.dependencies]
diff --git a/src/tests/prime_sieve/Cargo.toml b/src/tests/prime_sieve/Cargo.toml
new file mode 100644
index 0000000..294a977
--- /dev/null
+++ b/src/tests/prime_sieve/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "prime_sieve"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+primrose-library = { path = "../../crates/library" }
+
+[dev-dependencies]
+criterion = { workspace = true }
+
+[[bench]]
+name = "main"
+harness = false
diff --git a/src/tests/prime_sieve/benches/main.rs b/src/tests/prime_sieve/benches/main.rs
new file mode 100644
index 0000000..fd04578
--- /dev/null
+++ b/src/tests/prime_sieve/benches/main.rs
@@ -0,0 +1,13 @@
+use criterion::BenchmarkId;
+use criterion::Criterion;
+use criterion::{criterion_group, criterion_main};
+
+fn bench_sieve(c: &mut Criterion) {
+ let size: usize = 10;
+ c.bench_with_input(BenchmarkId::new("prime_sieve", size), &size, |b, &n| {
+ b.iter(|| prime_sieve::prime_sieve(n));
+ });
+}
+
+criterion_group!(benches, bench_sieve);
+criterion_main!(benches);
diff --git a/src/tests/prime_sieve/src/lib.rs b/src/tests/prime_sieve/src/lib.rs
new file mode 100644
index 0000000..8d53e30
--- /dev/null
+++ b/src/tests/prime_sieve/src/lib.rs
@@ -0,0 +1,55 @@
+#![feature(type_alias_impl_trait)]
+
+mod types;
+use types::*;
+
+/// Find all primes < `n` using the sieve of eratosthenes
+pub fn prime_sieve(n: usize) -> Primes<usize> {
+ // Add numbers to sieve through
+ let mut sieve = Sieve::default();
+ (2..n).rev().for_each(|x| sieve.push(x));
+
+ let mut primes = Primes::default();
+ while let Some(x) = sieve.pop() {
+ primes.insert(x);
+
+ // remove all multiples of x from sieve
+ let mut sieved = 2 * x;
+ while sieved < n {
+ sieve.remove(sieved);
+ sieved += x;
+ }
+ }
+
+ primes
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::prime_sieve;
+ use primrose_library::traits::*;
+ use std::fmt::Display;
+
+ fn assert_coneq<E: Display, T: Container<E>>(mut left: T, right: Vec<E>) {
+ assert_eq!(left.len(), right.len(), "length must be equal");
+ for i in right.into_iter() {
+ assert!(left.contains(&i), "must container element {}", i);
+ }
+ }
+
+ #[test]
+ fn test10() {
+ assert_coneq(prime_sieve(10), vec![2, 3, 5, 7]);
+ }
+
+ #[test]
+ fn test100() {
+ assert_coneq(
+ prime_sieve(100),
+ 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,
+ ],
+ );
+ }
+}
diff --git a/src/tests/prime_sieve/src/types.pr.rs b/src/tests/prime_sieve/src/types.pr.rs
new file mode 100644
index 0000000..2006302
--- /dev/null
+++ b/src/tests/prime_sieve/src/types.pr.rs
@@ -0,0 +1,13 @@
+/*SPEC*
+property lifo<T> {
+ \c <: (Stack) -> (forall \x -> ((equal? (pop ((push c) x))) x))
+}
+
+property ascending<T> {
+ \c -> ((for-all-consecutive-pairs c) leq?)
+}
+
+
+type Sieve<S> = {c impl (Container, Stack) | (lifo c)}
+type Primes<S> = {c impl (Container, Stack) | (ascending c)}
+*ENDSPEC*/