diff --git a/README.rst b/README.rst index 19818acc..5aa94225 100644 --- a/README.rst +++ b/README.rst @@ -88,7 +88,7 @@ Olivia's Project Euler Solutions | | GraalPy 23.1+ |br| | | |CodeQL| |br| | | | Browser [#]_ | | |PythonLint| | +------------+----------------------------+--------+-------------------+ -| Rust | 1.69+ |br| | 36 | |Rust| |br| | +| Rust | 1.69+ |br| | 38 | |Rust| |br| | | | Browser [#]_ | | |Rs-Cov| |br| | | | | | |RustClippy| | +------------+----------------------------+--------+-------------------+ diff --git a/docs/index.rst b/docs/index.rst index 073d31c1..219698fd 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -226,7 +226,7 @@ Problems Solved +-----------+------------+------------+------------+------------+------------+------------+------------+ |:prob:`145`| | | | | |:py-d:`0145`| | +-----------+------------+------------+------------+------------+------------+------------+------------+ -|:prob:`187`| | | | | |:py-d:`0187`| | +|:prob:`187`| | | | | |:py-d:`0187`|:rs-d:`0187`| +-----------+------------+------------+------------+------------+------------+------------+------------+ |:prob:`206`| | | | | |:py-d:`0206`| | +-----------+------------+------------+------------+------------+------------+------------+------------+ diff --git a/docs/src/rust/p0044.rst b/docs/src/rust/p0044.rst new file mode 100644 index 00000000..f768f49a --- /dev/null +++ b/docs/src/rust/p0044.rst @@ -0,0 +1,20 @@ +Rust Implementation of Problem 44 +================================= + +View source code :source:`rust/src/p0044.rs` + +Includes +-------- + +- `math <./lib/math.html>`_ + +Problem Solution +---------------- + +.. rust:fn:: pub fn p0044::p0044() -> utils::Answer + +.. literalinclude:: ../../../rust/src/p0044.rs + :language: rust + :linenos: + +.. tags:: figurate-number diff --git a/docs/src/rust/p0187.rst b/docs/src/rust/p0187.rst new file mode 100644 index 00000000..22751496 --- /dev/null +++ b/docs/src/rust/p0187.rst @@ -0,0 +1,20 @@ +Rust Implementation of Problem 187 +================================== + +View source code :source:`rust/src/p0187.rs` + +Includes +-------- + +- `primes <./lib/primes.html>`_ + +Problem Solution +---------------- + +.. rust:fn:: pub fn p0187::p0187() -> utils::Answer + +.. literalinclude:: ../../../rust/src/p0187.rs + :language: rust + :linenos: + +.. tags:: factorization, prime-number, rust-iterator diff --git a/rust/README.rst b/rust/README.rst index e75998d5..dae14174 100644 --- a/rust/README.rst +++ b/rust/README.rst @@ -85,6 +85,7 @@ Problems Solved - ☒ `34 <./src/p0034.rs>`__ - ☒ `36 <./src/p0036.rs>`__ - ☒ `37 <./src/p0037.rs>`__ +- ☒ `44 <./src/p0044.rs>`__ - ☒ `45 <./src/p0045.rs>`__ - ☒ `53 <./src/p0053.rs>`__ - ☒ `59 <./src/p0059.rs>`__ @@ -93,6 +94,7 @@ Problems Solved - ☒ `76 <./src/p0076.rs>`__ - ☒ `77 <./src/p0077.rs>`__ - ☒ `87 <./src/p0087.rs>`__ +- ☒ `187 <./src/p0187.rs>`__ - ☒ `357 <./src/p0357.rs>`__ - ☒ `836 <./src/p0836.rs>`__ diff --git a/rust/src/include/math.rs b/rust/src/include/math.rs index e3a2c84a..68525ced 100644 --- a/rust/src/include/math.rs +++ b/rust/src/include/math.rs @@ -83,3 +83,19 @@ where I: Copy + From + From + NumAssign + PartialOrd + CheckedMul + Deb } return answer; } + +pub fn triangle(n: I) -> I where I: NumAssign + Copy { + let two = one::() + one(); + return n * (n + one()) / two; +} + +pub fn pentagonal(n: I) -> I where I: NumAssign + Copy { + let two = one::() + one(); + let three = two + one(); + return n * (three * n - one()) / two; +} + +pub fn hexagonal(n: I) -> I where I: NumAssign + Copy { + let two = one::() + one(); + return n * (two * n - one()); +} diff --git a/rust/src/include/problems.rs b/rust/src/include/problems.rs index c7069922..e953ce97 100644 --- a/rust/src/include/problems.rs +++ b/rust/src/include/problems.rs @@ -8,6 +8,7 @@ use crate::p0027::p0027; use crate::p0034::p0034; use crate::p0036::p0036; use crate::p0037::p0037; +use crate::p0044::p0044; use crate::p0045::p0045; use crate::p0053::p0053; use crate::p0059::p0059; @@ -16,6 +17,7 @@ use crate::p0069::p0069; use crate::p0076::p0076; use crate::p0077::p0077; use crate::p0087::p0087; +use crate::p0187::p0187; use crate::p0357::p0357; use crate::p0836::p0836; @@ -52,6 +54,7 @@ pub fn get_problem<'b>(n: usize) -> Option> { 34 => Some(( &34, p0034, false)), 36 => Some(( &36, p0036, false)), 37 => Some(( &37, p0037, true)), + 44 => Some(( &44, p0044, false)), 45 => Some(( &45, p0045, false)), 53 => Some(( &53, p0053, false)), 59 => Some(( &59, p0059, false)), @@ -60,6 +63,7 @@ pub fn get_problem<'b>(n: usize) -> Option> { 76 => Some(( &76, p0076, false)), 77 => Some(( &77, p0077, false)), 87 => Some(( &87, p0087, false)), + 187 => Some((&187, p0187, false)), 357 => Some((&357, p0357, true)), 836 => Some((&836, p0836, false)), _ => None, diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 994c99b7..ba6f3d18 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -13,6 +13,7 @@ pub mod p0027; pub mod p0034; pub mod p0036; pub mod p0037; +pub mod p0044; pub mod p0045; pub mod p0053; pub mod p0059; @@ -21,6 +22,7 @@ pub mod p0069; pub mod p0076; pub mod p0077; pub mod p0087; +pub mod p0187; pub mod p0357; pub mod p0836; diff --git a/rust/src/main.rs b/rust/src/main.rs index 3a8f4d41..a959c1fb 100644 --- a/rust/src/main.rs +++ b/rust/src/main.rs @@ -30,6 +30,7 @@ pub mod p0027; pub mod p0034; pub mod p0036; pub mod p0037; +pub mod p0044; pub mod p0045; pub mod p0053; pub mod p0059; @@ -38,6 +39,7 @@ pub mod p0069; pub mod p0076; pub mod p0077; pub mod p0087; +pub mod p0187; pub mod p0357; pub mod p0836; @@ -83,6 +85,7 @@ seq!(N in 01..=20 { #[case::problem_34(34)] #[case::problem_36(36)] #[case::problem_37(37)] +#[case::problem_44(44)] #[case::problem_45(45)] #[case::problem_53(53)] #[case::problem_59(59)] @@ -91,6 +94,7 @@ seq!(N in 01..=20 { #[case::problem_76(76)] #[case::problem_77(77)] #[case::problem_87(87)] +#[case::problem_187(187)] // #[case::problem_357(357)] #[case::problem_836(836)] fn test_problem(#[case] id: usize) -> Result<(), String> { diff --git a/rust/src/p0044.rs b/rust/src/p0044.rs new file mode 100644 index 00000000..af78a379 --- /dev/null +++ b/rust/src/p0044.rs @@ -0,0 +1,41 @@ +/* +Project Euler Problem 44 + +Problem: + +Pentagonal numbers are generated by the formula, Pn=n(3n−1)/2. The first ten pentagonal numbers are: + +1, 5, 12, 22, 35, 51, 70, 92, 117, 145, ... + +It can be seen that P4 + P7 = 22 + 70 = 92 = P8. However, their difference, 70 − 22 = 48, is not pentagonal. + +Find the pair of pentagonal numbers, Pj and Pk, for which their sum and difference are pentagonal and D = ``|Pk − Pj|`` +is minimised; what is the value of D? +*/ +use std::cmp::min; + +use crate::include::math::pentagonal; +use crate::include::utils::Answer; + + +fn is_pentagonal(x: i64) -> bool { + let check = 24 * x + 1; + let root = check.isqrt(); + if root * root != check { + return false; + } + return (1 + root) % 6 == 0; +} + +pub fn p0044() -> Answer { + let mut d: i64 = 1_000_000_000_000; + let pentagonals = (1..2_500).map(pentagonal).collect::>(); + for (idx, &k) in pentagonals.iter().enumerate() { + for &j in &pentagonals[idx..] { + if is_pentagonal(j + k) && is_pentagonal(k - j) { + d = min(d, (k - j).abs()); + } + } + } + return Answer::Int(d.into()); +} diff --git a/rust/src/p0045.rs b/rust/src/p0045.rs index 9008da68..9a376fca 100644 --- a/rust/src/p0045.rs +++ b/rust/src/p0045.rs @@ -10,39 +10,28 @@ Hexagonal Hn=n(2n−1) 1, 6, 15, 28, 45, ... It can be verified that T285 = P165 = H143 = 40755. */ +use crate::include::math::{hexagonal,pentagonal,triangle}; use crate::include::utils::Answer; -fn t(n: u64) -> u64 { - return n * (n + 1) / 2; -} - -fn p(n: u64) -> u64 { - return n * (3 * n - 1) / 2; -} - -fn h(n: u64) -> u64 { - return n * (2 * n - 1); -} - pub fn p0045() -> Answer { let mut t_idx: u64 = 286; let mut p_idx: u64 = 166; let mut h_idx: u64 = 144; - let mut t_val = t(t_idx); - let mut p_val = p(p_idx); - let mut h_val = h(h_idx); + let mut t_val = triangle(t_idx); + let mut p_val = pentagonal(p_idx); + let mut h_val = hexagonal(h_idx); while !(t_val == p_val && p_val == h_val) { while t_val < p_val || t_val < h_val { t_idx += 1; - t_val = t(t_idx); + t_val = triangle(t_idx); } while p_val < t_val || p_val < h_val { p_idx += 1; - p_val = p(p_idx); + p_val = pentagonal(p_idx); } while h_val < p_val || h_val < t_val { h_idx += 1; - h_val = h(h_idx); + h_val = hexagonal(h_idx); } } return Answer::Int(t_val.into()); diff --git a/rust/src/p0187.rs b/rust/src/p0187.rs new file mode 100644 index 00000000..2a0d50c1 --- /dev/null +++ b/rust/src/p0187.rs @@ -0,0 +1,43 @@ +/* +Project Euler Problem 187 + +I was able to chain this with a previous problem. Probably a suboptimal +solution because of it, but it felt prettier this way. + +I was able to add a short-circuited fail case to the is_prime() method, though + +Revision 1: + +Switched to a set comprehension with caching. This means that I can remove it +from the slow list. + +Problem: + +A composite is a number containing at least two prime factors. For example, +15 = 3 × 5; 9 = 3 × 3; 12 = 2 × 2 × 3. + +There are ten composites below thirty containing precisely two, not necessarily +distinct, prime factors: 4, 6, 9, 10, 14, 15, 21, 22, 25, 26. + +How many composite integers, n < 10**8, have precisely two, not necessarily +distinct, prime factors? +*/ +use std::collections::HashSet; + +use crate::include::primes::primes_until; +use crate::include::utils::Answer; + +pub fn p0187() -> Answer { + let ten_8: u64 = 10_u64.pow(8); + let cached_primes: Vec = primes_until::(ten_8 / 2 + 1).collect(); + let mut seen: HashSet = HashSet::new(); + for &y in cached_primes.iter() { + for &x in cached_primes.iter() { + if x > ten_8 / y { + break; + } + seen.insert(x * y); + } + } + return Answer::Int((seen.len() as u64).into()); +}