diff --git a/src/euler27/Cargo.toml b/src/euler27/Cargo.toml index 2b3f298..9930c4a 100644 --- a/src/euler27/Cargo.toml +++ b/src/euler27/Cargo.toml @@ -4,3 +4,10 @@ version = "0.1.0" edition = "2024" [dependencies] + +[dev-dependencies] +rstest = "0.25.0" + +[profile.release] +debug = true +lto = "fat" diff --git a/src/euler27/src/main.rs b/src/euler27/src/main.rs index 6cfd4b1..30abf8d 100644 --- a/src/euler27/src/main.rs +++ b/src/euler27/src/main.rs @@ -1,15 +1,27 @@ use std::collections::HashMap; fn main() { - let q = Quadratic { a: 1, b: 41 }; + let mut primes = Primes::new(); - let mut p = Primes::new(); + let mut maximum_number_primes = 0; + let mut maximum_product = 0; - for n in 0..=39 { - let result = q.calculate(n); - dbg!(p.is_prime(n)); - println!("{}", result); + for a in -999..=999 { + for b in -1000..=1000 { + let quadratic = Quadratic::new(a, b); + + 'inner: for number_consecutive_primes in 0.. { + if !primes.is_prime(quadratic.calculate(number_consecutive_primes)) { + if number_consecutive_primes > maximum_number_primes { + maximum_number_primes = number_consecutive_primes; + maximum_product = quadratic.product(); + } + break 'inner; + } + } + } } + println!("{maximum_product}"); } struct Quadratic { @@ -18,9 +30,17 @@ struct Quadratic { } impl Quadratic { + fn new(a: isize, b: isize) -> Self { + Self { a, b } + } + fn calculate(&self, n: isize) -> isize { n.pow(2) + self.a * n + self.b } + + fn product(&self) -> isize { + self.a * self.b + } } struct Primes(HashMap); @@ -32,6 +52,9 @@ impl Primes { } fn is_prime(&mut self, number: isize) -> bool { + if number < 2 { + return false; + } let value = self.0.get(&number); if let Some(result) = value { return *result; @@ -42,6 +65,67 @@ impl Primes { } fn test_primality(number: isize) -> bool { - let max = (number as f64).sqrt(); + let max = (number as f64).sqrt().floor() as isize; + for divisor in 2..=max { + if number % divisor == 0 { + return false; + } + } + true + } +} + +#[cfg(test)] +mod tests { + use crate::{Primes, Quadratic}; + + use rstest::rstest; + + #[rstest] + #[case(2, true)] + #[case(3, true)] + #[case(7, true)] + #[case(9, false)] + #[case(27, false)] + fn test_basic_primes(#[case] number: isize, #[case] expected: bool) { + let mut primes = Primes::new(); + let result = primes.is_prime(number); + assert_eq!(result, expected) + } + + #[test] + fn test_eulers_equation() { + let q = Quadratic::new(1, 41); + let mut primes = Primes::new(); + for n in 0..=39 { + let possible_prime = q.calculate(n); + let result = primes.is_prime(possible_prime); + assert!(result); + } + + let possible_prime = q.calculate(40); + let result = primes.is_prime(possible_prime); + assert!(!result); + } + + #[test] + fn test_second_equation() { + let q = Quadratic::new(-79, 1601); + let mut primes = Primes::new(); + for n in 0..=79 { + let possible_prime = q.calculate(n); + let result = primes.is_prime(possible_prime); + assert!(result); + } + + let possible_prime = q.calculate(80); + let result = primes.is_prime(possible_prime); + assert!(!result); + } + + #[test] + fn product() { + let product = Quadratic::new(-79, 1601).product(); + assert_eq!(product, -126479) } }