Skip to content

Commit

Permalink
Solve 44, 187 in rust
Browse files Browse the repository at this point in the history
  • Loading branch information
LivInTheLookingGlass committed Aug 27, 2024
1 parent 488ce36 commit 4b9dd6f
Show file tree
Hide file tree
Showing 12 changed files with 164 additions and 20 deletions.
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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| |
+------------+----------------------------+--------+-------------------+
Expand Down
2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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`| |
+-----------+------------+------------+------------+------------+------------+------------+------------+
Expand Down
20 changes: 20 additions & 0 deletions docs/src/rust/p0044.rst
Original file line number Diff line number Diff line change
@@ -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
20 changes: 20 additions & 0 deletions docs/src/rust/p0187.rst
Original file line number Diff line number Diff line change
@@ -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
2 changes: 2 additions & 0 deletions rust/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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>`__
Expand All @@ -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>`__

16 changes: 16 additions & 0 deletions rust/src/include/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,19 @@ where I: Copy + From<u8> + From<u64> + NumAssign + PartialOrd + CheckedMul + Deb
}
return answer;
}

pub fn triangle<I>(n: I) -> I where I: NumAssign + Copy {
let two = one::<I>() + one();
return n * (n + one()) / two;
}

pub fn pentagonal<I>(n: I) -> I where I: NumAssign + Copy {
let two = one::<I>() + one();
let three = two + one();
return n * (three * n - one()) / two;
}

pub fn hexagonal<I>(n: I) -> I where I: NumAssign + Copy {
let two = one::<I>() + one();
return n * (two * n - one());
}
4 changes: 4 additions & 0 deletions rust/src/include/problems.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

Expand Down Expand Up @@ -52,6 +54,7 @@ pub fn get_problem<'b>(n: usize) -> Option<ProblemRef<'b>> {
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)),
Expand All @@ -60,6 +63,7 @@ pub fn get_problem<'b>(n: usize) -> Option<ProblemRef<'b>> {
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,
Expand Down
2 changes: 2 additions & 0 deletions rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

Expand Down
4 changes: 4 additions & 0 deletions rust/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

Expand Down Expand Up @@ -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)]
Expand All @@ -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> {
Expand Down
44 changes: 44 additions & 0 deletions rust/src/p0044.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
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 root = ((24 * x + 1) as f64).sqrt();
let iroot = root.round();
if iroot as f64 != root {
return false;
}
if (1.0 + iroot) % 6.0 != 0.0 {
return false;
}
return true;
}

pub fn p0044() -> Answer {
let mut d: i64 = 1_000_000_000_000;
let pentagonals = (1..2_500).map(pentagonal).collect::<Vec<i64>>();
for (idx, &k) in pentagonals.iter().enumerate() {
for &j in &pentagonals[idx..] {
if is_pentagonal(j + k) != 0 && is_pentagonal(k - j) != 0 {
d = min(d, (k - j).abs());
}
}
}
return Answer::Int(d.into());
}
25 changes: 7 additions & 18 deletions rust/src/p0045.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
43 changes: 43 additions & 0 deletions rust/src/p0187.rs
Original file line number Diff line number Diff line change
@@ -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<u64> = primes_until::<u64>(ten_8 / 2 + 1).collect();
let mut seen: HashSet<u64> = 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());
}

0 comments on commit 4b9dd6f

Please sign in to comment.