Remove get_recurring from fraction as it is not really useful I think other than for euler 26
This commit is contained in:
parent
5c802bf310
commit
b44908429a
@ -1,4 +1,4 @@
|
||||
use std::{collections::HashSet, error::Error};
|
||||
use std::error::Error;
|
||||
|
||||
use crate::number::Number;
|
||||
|
||||
@ -31,38 +31,10 @@ impl Fraction {
|
||||
self.numerator = self.numerator.clone() / gcd.clone();
|
||||
self.denominator = self.denominator.clone() / gcd.clone();
|
||||
}
|
||||
|
||||
pub fn get_repeating(&self) -> Number {
|
||||
let mut memory = HashSet::new();
|
||||
let mut div_with = self.numerator.clone();
|
||||
let mut repetition = Vec::new();
|
||||
let num_len = self.numerator.digits.len();
|
||||
for _ in 0..num_len {
|
||||
div_with = div_with * 10;
|
||||
}
|
||||
loop {
|
||||
println!("{div_with}/{}", self.denominator.clone());
|
||||
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]);
|
||||
return Number {
|
||||
digits: repetition,
|
||||
sign: crate::number::Sign::Positif,
|
||||
};
|
||||
}
|
||||
memory.insert(rem.clone());
|
||||
repetition.push(div.digits[0]);
|
||||
div_with = rem * 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::number::Number;
|
||||
|
||||
use super::Fraction;
|
||||
|
||||
#[test]
|
||||
@ -76,11 +48,4 @@ mod test {
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_repeating() {
|
||||
let f = Fraction::new(1.into(), 7.into()).unwrap();
|
||||
let rep = f.get_repeating();
|
||||
assert_eq!(rep, Number::from("142857"));
|
||||
}
|
||||
}
|
||||
|
119
src/number.rs
119
src/number.rs
@ -110,7 +110,7 @@ impl Number {
|
||||
pub fn pow(self, n: u32) -> Self {
|
||||
let mut result = self.clone();
|
||||
if ((self.digits.len() * 8) as u32) < isize::BITS {
|
||||
let number = isize::from(self);
|
||||
let number = isize::try_from(self).unwrap();
|
||||
for _i in 1..n {
|
||||
result = result * number;
|
||||
}
|
||||
@ -127,7 +127,7 @@ impl Number {
|
||||
pub fn fact(self) -> Self {
|
||||
let mut fact = Number::from(1);
|
||||
if ((self.digits.len() * 8) as u32) < isize::BITS {
|
||||
let max = isize::from(self);
|
||||
let max = isize::try_from(self).unwrap();
|
||||
for n in 1..=max {
|
||||
fact = fact * n;
|
||||
}
|
||||
@ -213,13 +213,19 @@ impl Number {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Number> for isize {
|
||||
fn from(value: Number) -> Self {
|
||||
impl TryFrom<Number> for isize {
|
||||
type Error = Box<dyn Error>;
|
||||
|
||||
fn try_from(value: Number) -> Result<Self, Self::Error> {
|
||||
let mut num = 0;
|
||||
for (pos, &digit) in value.digits.iter().rev().enumerate() {
|
||||
num += digit * 10isize.pow(pos as u32);
|
||||
let mul = digit.checked_mul(10isize.pow(pos as u32));
|
||||
if mul.is_none() {
|
||||
return Err(Box::from("Cannot convert Number to isize. Too big."));
|
||||
}
|
||||
num += mul.unwrap();
|
||||
}
|
||||
num
|
||||
Ok(num)
|
||||
}
|
||||
}
|
||||
|
||||
@ -408,6 +414,51 @@ impl Rem for Number {
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for Number {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for Number {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
if self.sign == Sign::Negatif && other.sign == Sign::Positif {
|
||||
return Ordering::Less;
|
||||
} else if self.sign == Sign::Positif && other.sign == Sign::Negatif {
|
||||
return Ordering::Greater;
|
||||
}
|
||||
if self.digits.len() < other.digits.len() {
|
||||
if self.sign == Sign::Positif {
|
||||
return Ordering::Less;
|
||||
} else if self.sign == Sign::Negatif {
|
||||
return Ordering::Greater;
|
||||
}
|
||||
} else if self.digits.len() > other.digits.len() {
|
||||
if self.sign == Sign::Positif {
|
||||
return Ordering::Greater;
|
||||
} else if self.sign == Sign::Negatif {
|
||||
return Ordering::Less;
|
||||
}
|
||||
}
|
||||
for pair in zip(&self.digits, &other.digits) {
|
||||
if pair.0 < pair.1 {
|
||||
if self.sign == Sign::Positif {
|
||||
return Ordering::Less;
|
||||
} else if self.sign == Sign::Negatif {
|
||||
return Ordering::Greater;
|
||||
}
|
||||
} else if pair.0 > pair.1 {
|
||||
if self.sign == Sign::Positif {
|
||||
return Ordering::Greater;
|
||||
} else if self.sign == Sign::Negatif {
|
||||
return Ordering::Less;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ordering::Equal
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod number_tests {
|
||||
use crate::number::{Number, Sign};
|
||||
@ -450,4 +501,60 @@ mod number_tests {
|
||||
assert_eq!(digit_4, 2);
|
||||
assert_eq!(digit_5, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cmp_eq_pos() {
|
||||
let a = Number::from(1);
|
||||
let b = Number::from(1);
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cmp_eq_neg() {
|
||||
let a = Number::from(-1);
|
||||
let b = Number::from(-1);
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cmp_pos_neg() {
|
||||
let a = Number::from(1);
|
||||
let b = Number::from(-1);
|
||||
assert!(a > b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cmp_neg_pos() {
|
||||
let a = Number::from(-1);
|
||||
let b = Number::from(1);
|
||||
assert!(a < b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cmp_short_neg() {
|
||||
let a = Number::from(-1);
|
||||
let b = Number::from(-10);
|
||||
assert!(a > b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cmp_short_pos() {
|
||||
let a = Number::from(1);
|
||||
let b = Number::from(10);
|
||||
assert!(a < b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cmp_long_neg() {
|
||||
let a = Number::from(-10);
|
||||
let b = Number::from(-1);
|
||||
assert!(a < b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cmp_long_pos() {
|
||||
let a = Number::from(10);
|
||||
let b = Number::from(1);
|
||||
assert!(a > b);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user