diff --git a/README.rst b/README.rst index 7f6f036e..9f1044d2 100644 --- a/README.rst +++ b/README.rst @@ -60,7 +60,7 @@ LivInTheLookingGlass’s Project Euler solutions | | Pypy 3.6+ |br| | | |Py-Cov| | | | GraalPy 23.1+ | | | +------------+-------------------------+--------+-------------------+ -| Rust | 1.69+ | 16 | |Rust| |br| | +| Rust | 1.69+ | 15 | |Rust| |br| | | | | | |Rs-Cov| | +------------+-------------------------+--------+-------------------+ | Documentation | |Pages| | diff --git a/docs/index.rst b/docs/index.rst index ef9b0100..095fb377 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -266,7 +266,7 @@ Key: +-----------+------------+------------+------------+------------+------------+------------+ |:prob:`206`| | | | |:py-d:`0206`| | +-----------+------------+------------+------------+------------+------------+------------+ -|:prob:`357`| | | | |:py-s:`0357`|:rs-d:`0357`| +|:prob:`357`| | | | |:py-s:`0357`|:rs-i:`0357`| +-----------+------------+------------+------------+------------+------------+------------+ .. toctree:: diff --git a/rust/src/main.rs b/rust/src/main.rs index 76ef4fb4..31616114 100644 --- a/rust/src/main.rs +++ b/rust/src/main.rs @@ -52,7 +52,7 @@ fn main() { } #[cfg(test)] -seq!(N in 0..16 { +seq!(N in 0..15 { #[rstest] #[timeout(Duration::new(60, 0))] #( diff --git a/rust/src/math.rs b/rust/src/math.rs index 5edd8248..02a00996 100644 --- a/rust/src/math.rs +++ b/rust/src/math.rs @@ -1,9 +1,20 @@ use std::cmp::PartialOrd; +use std::mem::size_of; use num_traits::NumAssign; use num_traits::one; -pub fn factorial>(n: u8) -> I { +const MAX_FACTORIAL: [usize; 16] = [ + 5, // u8 + 8, // u16 + 10, 12, // u32 + 14, 16, 18, 20, // u64 + 22, 24, 25, 27, 29, 30, 32, 34 // u128 +]; + +pub fn factorial(n: u8) -> I +where I: NumAssign + From +{ let mut answer: I = one(); for i in 2..=n { answer *= i.into(); @@ -11,7 +22,15 @@ pub fn factorial>(n: u8) -> I { return answer } -pub fn n_choose_r + NumAssign + PartialOrd>(n: usize, r: usize) -> I { +pub fn n_choose_r(n: usize, r: usize) -> I +where I: Copy + From + From + NumAssign + PartialOrd +{ + if n < r { + panic!("Out of function's bounds"); + } + if n < MAX_FACTORIAL[size_of::() as usize] { + return factorial::(n as u8) / factorial::(r as u8); + } // slow path for larger numbers let mut answer: I = one(); let mut tmp: I; diff --git a/rust/src/primes.rs b/rust/src/primes.rs index 4bead42f..27441d59 100644 --- a/rust/src/primes.rs +++ b/rust/src/primes.rs @@ -8,14 +8,18 @@ use num_traits::zero; use num_traits::one; use itertools::Itertools; -pub struct Eratosthenes { +pub struct Eratosthenes +where I: NumAssign + Bounded + PartialOrd + Eq + Hash + Copy +{ sieve: HashMap>, prime: I, candidate: I, limit: I, } -impl Default for Eratosthenes { +impl Default for Eratosthenes +where I: NumAssign + Bounded + PartialOrd + Eq + Hash + Copy +{ fn default() -> Self { return Eratosthenes::{ sieve: HashMap::new(), @@ -26,7 +30,9 @@ impl Default for Eratost } } -impl Eratosthenes { +impl Eratosthenes +where I: NumAssign + Bounded + PartialOrd + Eq + Hash + Copy +{ pub fn new() -> Eratosthenes { return Default::default(); } @@ -39,7 +45,9 @@ impl Eratosthenes { } } -impl Iterator for Eratosthenes { +impl Iterator for Eratosthenes +where I: NumAssign + Bounded + PartialOrd + Eq + Hash + Copy +{ type Item = I; fn next(&mut self) -> Option { @@ -72,19 +80,27 @@ impl Iterator for Eratos } } -pub fn primes() -> Eratosthenes { +pub fn primes() -> Eratosthenes +where I: NumAssign + Bounded + PartialOrd + Eq + Hash + Copy +{ return Eratosthenes::new(); } -pub fn primes_until(x: I) -> Eratosthenes { +pub fn primes_until(x: I) -> Eratosthenes +where I: NumAssign + Bounded + PartialOrd + Eq + Hash + Copy +{ return Eratosthenes::with_limit(x); } -pub struct PrimeFactors { +pub struct PrimeFactors +where I: NumAssign + Bounded + PartialOrd + Eq + Hash + Copy +{ number: I } -impl PrimeFactors { +impl PrimeFactors +where I: NumAssign + Bounded + PartialOrd + Eq + Hash + Copy +{ pub fn new(x: I) -> PrimeFactors { return PrimeFactors{ number: x @@ -92,7 +108,9 @@ impl PrimeFactors { } } -impl Iterator for PrimeFactors { +impl Iterator for PrimeFactors +where I: NumAssign + Bounded + PartialOrd + Eq + Hash + Copy +{ type Item = I; fn next(&mut self) -> Option { @@ -109,11 +127,15 @@ impl Iterator for PrimeF } } -pub fn prime_factors(x: I) -> PrimeFactors { +pub fn prime_factors(x: I) -> PrimeFactors +where I: NumAssign + Bounded + PartialOrd + Eq + Hash + Copy +{ return PrimeFactors::new(x); } -pub fn proper_divisors(x: I) -> Vec { +pub fn proper_divisors(x: I) -> Vec +where I: NumAssign + Bounded + Ord + Eq + Hash + Copy +{ let mut ret: Vec = vec![]; let factors: Vec = PrimeFactors::new(x).collect(); ret.extend(factors.clone()); @@ -127,7 +149,9 @@ pub fn proper_divisors(x: I) -> return ret; } -pub fn is_composite(x: I) -> I { +pub fn is_composite(x: I) -> I +where I: NumAssign + Bounded + PartialOrd + Eq + Hash + Copy +{ match prime_factors(x).next() { None => { return zero(); @@ -141,6 +165,8 @@ pub fn is_composite(x: I } } -pub fn is_prime(x: I) -> bool { +pub fn is_prime(x: I) -> bool +where I: NumAssign + Bounded + PartialOrd + Eq + Hash + Copy +{ return is_composite(x) == zero(); }