Skip to content

Commit

Permalink
Solve 36, 37, 45, 53 in rust
Browse files Browse the repository at this point in the history
  • Loading branch information
LivInTheLookingGlass committed Aug 26, 2024
1 parent 4d65f88 commit 9b9c7a7
Show file tree
Hide file tree
Showing 17 changed files with 316 additions and 51 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| | 29 | |Rust| |br| |
| Rust | 1.69+ |br| | 33 | |Rust| |br| |
| | Browser [#]_ | | |Rs-Cov| |br| |
| | | | |RustClippy| |
+------------+----------------------------+--------+-------------------+
Expand Down
4 changes: 4 additions & 0 deletions rust/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ Problems Solved
- ☒ `24 <./src/p0024.rs>`__
- ☒ `27 <./src/p0027.rs>`__
- ☒ `34 <./src/p0034.rs>`__
- ☒ `36 <./src/p0036.rs>`__
- ☒ `37 <./src/p0037.rs>`__
- ☒ `45 <./src/p0045.rs>`__
- ☒ `53 <./src/p0053.rs>`__
- ☒ `69 <./src/p0069.rs>`__
- ☒ `76 <./src/p0076.rs>`__
- ☒ `77 <./src/p0077.rs>`__
Expand Down
8 changes: 4 additions & 4 deletions rust/src/include/factors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub struct ProperDivisors<I>
next_size: usize,
}

pub fn proper_divisors<I>(num: I) -> ProperDivisors<I>
pub fn proper_divisors<I>(num: I) -> impl Iterator<Item = I>
where I: Hash + Zero + One + Add + Ord + Copy + Div<Output=I> + Rem<Output=I> + 'static
{
return ProperDivisors::<I>::new(num);
Expand Down Expand Up @@ -48,9 +48,9 @@ where I: Hash + Zero + One + Add + Ord + Copy + Div<Output=I> + Rem<Output=I> +
return None;
}
if self.next_size == 0 {
self.next_size += 1;
return Some(one());
}
self.next_size += 1;
return Some(one());
}
while self.curr_index < self.current_batch.len() {
let result = self.current_batch[self.curr_index];
self.curr_index += 1;
Expand Down
81 changes: 81 additions & 0 deletions rust/src/include/fibonacci.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
use std::ops::{Add,Mul};

use num_traits::{one,zero,One,Zero};

use crate::include::iter_cache::cache_iterator;

pub fn fib<I>() -> impl Iterator<Item = I> where I: Copy + Zero + One + Add + 'static {
return cache_iterator(Fibonacci::<I>::new());
}

pub fn fib_by_3<I>() -> impl Iterator<Item = I> where I: Copy + Zero + One + Add + Mul + 'static {
return cache_iterator(FibonacciBy3::<I>::new());
}

pub struct Fibonacci<I> {
a: I,
b: I,
}

impl<I> Default for Fibonacci<I> where I: Zero + One {
fn default() -> Self {
return Fibonacci::<I>{
a: zero(),
b: one(),
};
}
}

impl<I> Fibonacci<I> where I: Zero + One {
pub fn new() -> Self {
return Default::default();
}
}

impl<I> Iterator for Fibonacci<I> where I: Zero + One + Add + Copy {
type Item = I;

fn next(&mut self) -> Option<Self::Item> {
let prior_a = self.a;
let prior_b = self.b;
self.b = self.a + self.b;
self.a = prior_b;
return Some(prior_a);
}
}

pub struct FibonacciBy3<I> {
a: I,
b: I,
}

impl<I> Default for FibonacciBy3<I> where I: Zero + One + Add + Copy {
fn default() -> Self {
let two = one::<I>() + one();
let four = two + two;
return FibonacciBy3::<I>{
a: two,
b: four + four,
};
}
}

impl<I> FibonacciBy3<I> where I: Zero + One + Add + Copy {
pub fn new() -> Self {
return Default::default();
}
}

impl<I> Iterator for FibonacciBy3<I> where I: Zero + One + Add + Mul + Copy {
type Item = I;

fn next(&mut self) -> Option<Self::Item> {
let two = one::<I>() + one();
let four = two + two;
let prior_a = self.a;
let prior_b = self.b;
self.b = four * self.a + self.b;
self.a = prior_b;
return Some(prior_a);
}
}
8 changes: 8 additions & 0 deletions rust/src/include/iter_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ use std::sync::Once;
static INIT: Once = Once::new();
static mut CACHE_MAP: Option<RwLock<HashMap<(TypeId, TypeId), Mutex<Vec<Box<dyn std::any::Any>>>>>> = None;

pub fn cache_iterator<I, T>(iterator: I) -> impl Iterator<Item = T>
where
I: Iterator<Item = T> + 'static,
T: Copy + 'static
{
return CachingIterator::new(iterator);
}

pub struct CachingIterator<I, T>
where
I: Iterator<Item = T> + 'static,
Expand Down
1 change: 1 addition & 0 deletions rust/src/include/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod iter_cache;
pub mod factors;
pub mod fibonacci;
pub mod math;
pub mod primes;
pub mod problems;
Expand Down
37 changes: 12 additions & 25 deletions rust/src/include/primes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,15 @@ use std::ops::{Add,Div,Mul,Rem};

use num_traits::{one,zero,One,Zero};

use crate::include::iter_cache::CachingIterator;
use crate::include::iter_cache::cache_iterator;

pub struct Eratosthenes<I>
where I: Hash
{
pub struct Eratosthenes<I> where I: Hash {
sieve: HashMap<I, Vec<I>>,
prime: I,
candidate: I,
}

impl<I> Default for Eratosthenes<I>
where I: Hash + One + Zero + Add
{
impl<I> Default for Eratosthenes<I> where I: Hash + One + Zero + Add {
fn default() -> Self {
return Eratosthenes::<I>{
sieve: HashMap::new(),
Expand All @@ -27,17 +23,13 @@ where I: Hash + One + Zero + Add
}
}

impl<I> Eratosthenes<I>
where I: Hash + One + Zero + Add
{
impl<I> Eratosthenes<I> where I: Hash + One + Zero + Add {
pub fn new() -> Eratosthenes<I> {
return Default::default();
}
}

impl<I> Iterator for Eratosthenes<I>
where I: Hash + One + Zero + Add + Mul + Ord + Copy
{
impl<I> Iterator for Eratosthenes<I> where I: Hash + One + Zero + Add + Mul + Ord + Copy {
type Item = I;

fn next(&mut self) -> Option<Self::Item> {
Expand Down Expand Up @@ -68,25 +60,19 @@ where I: Hash + One + Zero + Add + Mul + Ord + Copy
}
}

pub fn primes<I>() -> impl Iterator<Item = I>
where I: Hash + One + Zero + Add + Mul + Ord + Copy + 'static
{
return CachingIterator::new(Eratosthenes::new());
pub fn primes<I>() -> impl Iterator<Item = I> where I: Hash + One + Zero + Add + Mul + Ord + Copy + 'static {
return cache_iterator(Eratosthenes::new());
}

pub fn primes_until<I>(x: I) -> impl Iterator<Item = I>
where I: Hash + One + Zero + Add + Mul + Ord + Copy + 'static
{
pub fn primes_until<I>(x: I) -> impl Iterator<Item = I> where I: Hash + One + Zero + Add + Mul + Ord + Copy + 'static {
return primes::<I>().take_while(move |n| *n < x);
}

pub struct PrimeFactors<I>
{
pub struct PrimeFactors<I> {
number: I
}

impl<I> PrimeFactors<I>
{
impl<I> PrimeFactors<I> {
pub fn new(x: I) -> PrimeFactors<I> {
return PrimeFactors{
number: x
Expand All @@ -113,7 +99,8 @@ where I: Hash + Zero + One + Add + Ord + Copy + Div<Output=I> + Rem<Output=I> +
}
}

pub fn prime_factors<I>(x: I) -> PrimeFactors<I>
pub fn prime_factors<I>(x: I) -> impl Iterator<Item = I>
where I: Hash + Zero + One + Add + Ord + Copy + Div<Output=I> + Rem<Output=I> + 'static
{
return PrimeFactors::new(x);
}
Expand Down
8 changes: 8 additions & 0 deletions rust/src/include/problems.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ use crate::p~N::p~N;
});
use crate::p0027::p0027;
use crate::p0034::p0034;
use crate::p0036::p0036;
use crate::p0037::p0037;
use crate::p0045::p0045;
use crate::p0053::p0053;
use crate::p0069::p0069;
use crate::p0076::p0076;
use crate::p0077::p0077;
Expand Down Expand Up @@ -44,6 +48,10 @@ pub fn get_problem<'b>(n: usize) -> Option<ProblemRef<'b>> {
24 => Some(( &24, p0024, false)),
27 => Some(( &27, p0027, true)),
34 => Some(( &34, p0034, false)),
36 => Some(( &36, p0036, false)),
37 => Some(( &37, p0037, false)),
45 => Some(( &45, p0045, false)),
53 => Some(( &53, p0053, false)),
69 => Some(( &69, p0069, false)),
76 => Some(( &76, p0076, false)),
77 => Some(( &77, p0077, false)),
Expand Down
9 changes: 8 additions & 1 deletion rust/src/include/utils.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::string::ToString;

#[cfg(not(any(target_arch="wasm32", target_arch="wasm64")))]
use std::fs::read_to_string;
#[cfg(not(any(target_arch="wasm32", target_arch="wasm64")))]
Expand Down Expand Up @@ -53,4 +55,9 @@ pub fn get_answer(n: usize) -> Answer {
}
}
panic!("Answer not found");
}
}

pub fn is_palindrome<I>(x: I) -> bool where I: ToString {
let s = x.to_string();
return s == s.chars().rev().collect::<String>();
}
4 changes: 4 additions & 0 deletions rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ pub mod p~N;
});
pub mod p0027;
pub mod p0034;
pub mod p0036;
pub mod p0037;
pub mod p0045;
pub mod p0053;
pub mod p0069;
pub mod p0076;
pub mod p0077;
Expand Down
30 changes: 26 additions & 4 deletions rust/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ pub mod p~N;
});
pub mod p0027;
pub mod p0034;
pub mod p0036;
pub mod p0037;
pub mod p0045;
pub mod p0053;
pub mod p0069;
pub mod p0076;
pub mod p0077;
Expand All @@ -40,9 +44,9 @@ fn main() {
for i in sieve {
println!("{}", i);
}
for i in 4..100 {
println!("{}: {:?}", i, factors::proper_divisors(i).collect::<Vec<u16>>());
}
for i in 4..100 {
println!("{}: {:?}", i, factors::proper_divisors(i).collect::<Vec<u16>>());
}
let supported = generate_supported_problems(false);

for id in supported {
Expand Down Expand Up @@ -73,6 +77,10 @@ seq!(N in 01..=20 {
#[case::problem_24(24)]
#[case::problem_27(27)]
#[case::problem_34(34)]
#[case::problem_36(36)]
#[case::problem_37(37)]
#[case::problem_45(45)]
#[case::problem_53(53)]
#[case::problem_69(69)]
#[case::problem_76(76)]
#[case::problem_77(77)]
Expand Down Expand Up @@ -100,7 +108,6 @@ fn test_problem(#[case] id: usize) -> Result<(), String> {
}
});


#[cfg(test)]
#[test]
fn test_primes() -> Result<(), String> {
Expand Down Expand Up @@ -128,3 +135,18 @@ fn test_prime_factors() -> Result<(), String> {
}
Ok(())
}

#[cfg(test)]
#[test]
fn test_proper_divisors() -> Result<(), String> {
for i in 4..1024 {
let divisors = factors::proper_divisors(i).collect::<Vec<u16>>();
for &factor in divisors.iter() {
if factor == 1 {
continue;
}
assert!(divisors.iter().any(|&x| x * factor == i));
}
}
Ok(())
}
12 changes: 2 additions & 10 deletions rust/src/p0002.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,9 @@ terms. By starting with 1 and 2, the first 10 terms will be:
By considering the terms in the Fibonacci sequence whose values do not exceed
four million, find the sum of the even-valued terms.
*/
use crate::include::fibonacci::fib_by_3;
use crate::include::utils::Answer;

pub fn p0002() -> Answer {
let mut answer: u64 = 0;
let mut i = 2;
let mut j = 8;
while i < 4000000 {
answer += i;
let tmp = 4 * j + i;
i = j;
j = tmp;
}
return Answer::Int(answer.into());
return Answer::Int(fib_by_3::<u64>().take_while(|x| *x < 4000000).sum::<u64>().into());
}
7 changes: 1 addition & 6 deletions rust/src/p0004.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,7 @@ Find the largest palindrome made from the product of two 3-digit numbers.
*/
use itertools::Itertools;

use crate::include::utils::Answer;

fn is_palindrome(x: u32) -> bool {
let s = x.to_string();
return s == s.chars().rev().collect::<String>();
}
use crate::include::utils::{is_palindrome,Answer};

pub fn p0004() -> Answer {
let mut answer: u32 = 0;
Expand Down
Loading

0 comments on commit 9b9c7a7

Please sign in to comment.