From 0e328b9be6a9c208038a8894b589186c5e24d9da Mon Sep 17 00:00:00 2001 From: Olivia Appleton Date: Fri, 23 Aug 2024 18:46:30 -0500 Subject: [PATCH] Solve p21, p23 in rust --- README.rst | 2 +- docs/index.rst | 4 +-- rust/README.rst | 2 ++ rust/src/include/problems.rs | 6 ++-- rust/src/lib.rs | 4 +-- rust/src/main.rs | 8 ++---- rust/src/p0021.rs | 47 ++++++++++++++++++++++++++++++ rust/src/p0023.rs | 56 ++++++++++++++++++++++++++++++++++++ 8 files changed, 114 insertions(+), 15 deletions(-) create mode 100644 rust/src/p0021.rs create mode 100644 rust/src/p0023.rs diff --git a/README.rst b/README.rst index 04a3ae18..38250fa2 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| | 28 | |Rust| |br| | +| Rust | 1.69+ |br| | 30 | |Rust| |br| | | | Browser [#]_ | | |Rs-Cov| |br| | | | | | |RustClippy| | +------------+----------------------------+--------+-------------------+ diff --git a/docs/index.rst b/docs/index.rst index 1f91bed4..a270aefa 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -116,11 +116,11 @@ Problems Solved +-----------+------------+------------+------------+------------+------------+------------+------------+ |:prob:`20` |:c-d:`0020` |:cp-d:`0020`|:cs-d:`0020`|:ja-d:`0020`|:js-d:`0020`|:py-d:`0020`|:rs-d:`0020`| +-----------+------------+------------+------------+------------+------------+------------+------------+ -|:prob:`21` | | | | | |:py-d:`0021`| | +|:prob:`21` | | | | | |:py-d:`0021`|:rs-d:`0021`| +-----------+------------+------------+------------+------------+------------+------------+------------+ |:prob:`22` |:c-d:`0022` |:cp-d:`0022`|:cs-d:`0022`|:ja-d:`0022`|:js-d:`0022`|:py-d:`0022`|:rs-d:`0022`| +-----------+------------+------------+------------+------------+------------+------------+------------+ -|:prob:`23` | | | | |:js-d:`0023`|:py-d:`0023`| | +|:prob:`23` | | | | |:js-d:`0023`|:py-d:`0023`|:rs-d:`0023`| +-----------+------------+------------+------------+------------+------------+------------+------------+ |:prob:`24` | | | | | |:py-d:`0024`|:rs-d:`0024`| +-----------+------------+------------+------------+------------+------------+------------+------------+ diff --git a/rust/README.rst b/rust/README.rst index 05677959..ef041342 100644 --- a/rust/README.rst +++ b/rust/README.rst @@ -77,7 +77,9 @@ Problems Solved - ☒ `18 <./src/p0018.rs>`__ - ☒ `19 <./src/p0019.rs>`__ - ☒ `20 <./src/p0020.rs>`__ +- ☒ `21 <./src/p0021.rs>`__ - ☒ `22 <./src/p0022.rs>`__ +- ☒ `23 <./src/p0023.rs>`__ - ☒ `24 <./src/p0024.rs>`__ - ☒ `27 <./src/p0027.rs>`__ - ☒ `34 <./src/p0034.rs>`__ diff --git a/rust/src/include/problems.rs b/rust/src/include/problems.rs index f11828d9..7c33ca42 100644 --- a/rust/src/include/problems.rs +++ b/rust/src/include/problems.rs @@ -1,11 +1,9 @@ use seq_macro::seq; use crate::include::utils::Answer; -seq!(N in 0001..=0020 { +seq!(N in 0001..=0024 { use crate::p~N::p~N; }); -use crate::p0022::p0022; -use crate::p0024::p0024; use crate::p0027::p0027; use crate::p0034::p0034; use crate::p0069::p0069; @@ -40,7 +38,9 @@ pub fn get_problem<'b>(n: usize) -> Option> { 18 => Some(( &18, p0018, false)), 19 => Some(( &19, p0019, false)), 20 => Some(( &20, p0020, false)), + 21 => Some(( &21, p0021, false)), 22 => Some(( &22, p0022, false)), + 23 => Some(( &23, p0023, false)), 24 => Some(( &24, p0024, false)), 27 => Some(( &27, p0027, false)), 34 => Some(( &34, p0034, false)), diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 673d36a8..24e1e1cb 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -6,11 +6,9 @@ use wasm_bindgen::prelude::*; use js_sys::Array; use seq_macro::seq; -seq!(N in 0001..=0020 { +seq!(N in 0001..=0024 { pub mod p~N; }); -pub mod p0022; -pub mod p0024; pub mod p0027; pub mod p0034; pub mod p0069; diff --git a/rust/src/main.rs b/rust/src/main.rs index f7db81e2..80a88038 100644 --- a/rust/src/main.rs +++ b/rust/src/main.rs @@ -20,11 +20,9 @@ use include::problems::get_problem; #[cfg(not(test))] use include::utils::Answer; use include::utils::get_answer; -seq!(N in 0001..=0020 { +seq!(N in 0001..=0024 { pub mod p~N; }); -pub mod p0022; -pub mod p0024; pub mod p0027; pub mod p0034; pub mod p0069; @@ -60,13 +58,11 @@ fn main() { } #[cfg(test)] -seq!(N in 01..=20 { +seq!(N in 01..=24 { #[rstest] #( #[case::problem_~N(N)] )* -#[case::problem_22(22)] -#[case::problem_24(24)] #[case::problem_27(27)] #[case::problem_34(34)] #[case::problem_69(69)] diff --git a/rust/src/p0021.rs b/rust/src/p0021.rs new file mode 100644 index 00000000..235528a3 --- /dev/null +++ b/rust/src/p0021.rs @@ -0,0 +1,47 @@ +/* +Project Euler Problem 21 + +I had to approach this by modifying the factors function from p0003, but it +seemed to work fairly well. + +Revision 1: + +Rewrote the proper_divisors function to be significantly faster by leveraging +the prime_factors object. + +Problem: + +Let d(n) be defined as the sum of proper divisors of n (numbers less than n +which divide evenly into n). If d(a) = b and d(b) = a, where a ≠ b, then a and +b are an amicable pair and each of a and b are called amicable numbers. + +For example, the proper divisors of 220 are 1, 2, 4, 5, 10, 11, 20, 22, 44, 55 +and 110; therefore d(220) = 284. The proper divisors of 284 are 1, 2, 4, 71 and +142; so d(284) = 220. + +Evaluate the sum of all the amicable numbers under 10000. +*/ +use std::collections::HashSet; + +use crate::include::factors::proper_divisors; +use crate::include::utils::Answer; + +fn d(n: u64) -> u64 { + return proper_divisors(n).sum::(); +} + +pub fn p0021() -> Answer { + let mut answer = 0; + let mut skip: HashSet = HashSet::new(); + for a in 0..10000 { + if skip.contains(&a) { + continue; + } + let b = d(a); + if a != b && d(b) == a { + answer += a + b; + skip.insert(b); + } + } + return Answer::Int(answer.into()); +} diff --git a/rust/src/p0023.rs b/rust/src/p0023.rs new file mode 100644 index 00000000..b52b5510 --- /dev/null +++ b/rust/src/p0023.rs @@ -0,0 +1,56 @@ +/* +Project Euler Problem 23 + +I had to approach this by modifying the factors function from p0003, but it +seemed to work fairly well. + +Problem: + +A perfect number is a number for which the sum of its proper divisors is +exactly equal to the number. For example, the sum of the proper divisors of 28 +would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28 is a perfect number. + +A number n is called deficient if the sum of its proper divisors is less than n +and it is called abundant if this sum exceeds n. + +As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the smallest +number that can be written as the sum of two abundant numbers is 24. By +mathematical analysis, it can be shown that all integers greater than 28123 can +be written as the sum of two abundant numbers. However, this upper limit cannot +be reduced any further by analysis even though it is known that the greatest +number that cannot be expressed as the sum of two abundant numbers is less than +this limit. + +Find the sum of all the positive integers which cannot be written as the sum of +two abundant numbers. +*/ +use std::collections::HashSet; + +use itertools::Itertools; + +use crate::include::factors::proper_divisors; +use crate::include::utils::Answer; + +pub fn p0023() -> Answer { + let mut abundant_sums: HashSet = HashSet::new(); + abundant_sums.insert(24); + let mut abundants: Vec = vec![]; + + for x in 12..28112 { + if proper_divisors(x).sum::() > x { + abundants.push(x); + } + } + for v in abundants.into_iter().combinations_with_replacement(2) { + let x = v[0]; + let y = v[1]; + abundant_sums.insert(x + y); + } + let mut sum = 0; + for x in 1..28124 { + if !abundant_sums.contains(&x) { + sum += x; + } + } + return Answer::Int(sum.into()); +}