Not yet working properly euler::problem_26

This commit is contained in:
Fabian Schmidt 2024-11-18 16:02:19 +01:00
parent 1df263be65
commit 5c802bf310
2 changed files with 45 additions and 21 deletions

View File

@ -4,8 +4,8 @@ use crate::number::Number;
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub struct Fraction { pub struct Fraction {
numerator: Number, pub numerator: Number,
denominator: Number, pub denominator: Number,
} }
pub struct Rational {} pub struct Rational {}
@ -25,6 +25,9 @@ impl Fraction {
pub fn reduce(&mut self) { pub fn reduce(&mut self) {
let gcd = Number::gcd(self.numerator.clone(), self.denominator.clone()); let gcd = Number::gcd(self.numerator.clone(), self.denominator.clone());
if gcd == self.denominator.clone() {
return;
}
self.numerator = self.numerator.clone() / gcd.clone(); self.numerator = self.numerator.clone() / gcd.clone();
self.denominator = self.denominator.clone() / gcd.clone(); self.denominator = self.denominator.clone() / gcd.clone();
} }
@ -33,9 +36,16 @@ impl Fraction {
let mut memory = HashSet::new(); let mut memory = HashSet::new();
let mut div_with = self.numerator.clone(); let mut div_with = self.numerator.clone();
let mut repetition = Vec::new(); let mut repetition = Vec::new();
let num_len = self.numerator.digits.len();
for _ in 0..num_len {
div_with = div_with * 10;
}
loop { loop {
let (div, rem) = Number::div_with_rem(div_with.clone(), self.denominator.clone()); println!("{div_with}/{}", self.denominator.clone());
if rem != 0.into() && memory.contains(&rem) { let (div, rem) =
Number::div_with_rem(div_with.clone(), self.denominator.clone()).unwrap();
println!("div: {div}, rem: {rem}");
if div == 0.into() || rem == 0.into() || memory.contains(&rem) {
repetition.push(div.digits[0]); repetition.push(div.digits[0]);
return Number { return Number {
digits: repetition, digits: repetition,
@ -43,14 +53,10 @@ impl Fraction {
}; };
} }
memory.insert(rem.clone()); memory.insert(rem.clone());
if div.digits.is_empty() {
div_with = div_with * 10;
} else {
repetition.push(div.digits[0]); repetition.push(div.digits[0]);
div_with = rem * 10; div_with = rem * 10;
} }
} }
}
} }
#[cfg(test)] #[cfg(test)]

View File

@ -1,4 +1,5 @@
use std::cmp::{min, Ordering}; use std::cmp::{min, Ordering};
use std::error::Error;
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
use std::iter::zip; use std::iter::zip;
use std::ops::{Add, Div, Mul, Rem, Sub}; use std::ops::{Add, Div, Mul, Rem, Sub};
@ -147,11 +148,14 @@ impl Number {
last_two.0 last_two.0
} }
pub fn div_with_rem(n1: Number, n2: Number) -> (Number, Number) { pub fn div_with_rem(n1: Number, n2: Number) -> Result<(Number, Number), Box<dyn Error>> {
if n2 == 0.into() {
return Err(Box::from("Division by 0"));
}
let n1_len = n1.digits.len(); let n1_len = n1.digits.len();
let n2_len = n2.digits.len(); let n2_len = n2.digits.len();
if n2_len > n1_len { if n2_len > n1_len {
return (Number::from(0), n2); return Ok((Number::from(0), n2));
} }
let dividend = n1.digits[..n2_len].to_vec(); let dividend = n1.digits[..n2_len].to_vec();
let mut quotient = vec![]; let mut quotient = vec![];
@ -183,7 +187,7 @@ impl Number {
}; };
res.handle_overflows(); res.handle_overflows();
for digit in res.clone().digits { for digit in res.clone().digits {
if digit != 0 { if digit != 0 || res.digits.len() == 1 {
break; break;
} }
res.digits.remove(0); res.digits.remove(0);
@ -194,7 +198,7 @@ impl Number {
} }
remainder.digits.remove(0); remainder.digits.remove(0);
} }
(res, remainder) Ok((res, remainder))
} }
pub fn gcd(mut a: Number, mut b: Number) -> Number { pub fn gcd(mut a: Number, mut b: Number) -> Number {
@ -253,11 +257,13 @@ impl From<isize> for Number {
sign = Sign::Negatif; sign = Sign::Negatif;
value *= -1; value *= -1;
} }
let num_len = if value > 0 { if value == 0 {
(value as f64 + 1.0).log10().ceil() as usize return Self {
} else { digits: vec![0],
1 sign: Sign::Positif,
}; };
}
let num_len = (value as f64 + 1.0).log10().ceil() as usize;
let mut digits = vec![]; let mut digits = vec![];
for digit_idx in 0..num_len { for digit_idx in 0..num_len {
let digit = Self::get_digit(value, digit_idx); let digit = Self::get_digit(value, digit_idx);
@ -390,7 +396,7 @@ impl Div for Number {
type Output = Self; type Output = Self;
fn div(self, rhs: Self) -> Self::Output { fn div(self, rhs: Self) -> Self::Output {
Self::div_with_rem(self, rhs).0 Self::div_with_rem(self, rhs).unwrap().0
} }
} }
@ -398,7 +404,7 @@ impl Rem for Number {
type Output = Self; type Output = Self;
fn rem(self, rhs: Self) -> Self::Output { fn rem(self, rhs: Self) -> Self::Output {
Self::div_with_rem(self, rhs).1 Self::div_with_rem(self, rhs).unwrap().1
} }
} }
@ -418,6 +424,18 @@ mod number_tests {
); );
} }
#[test]
fn test_from_0isize() {
let number = Number::from(0);
assert_eq!(
number,
Number {
digits: vec![0],
sign: Sign::Positif
}
);
}
#[test] #[test]
fn test_get_digit() { fn test_get_digit() {
let num = 12345; let num = 12345;