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;
|
use crate::number::Number;
|
||||||
|
|
||||||
@ -31,38 +31,10 @@ impl Fraction {
|
|||||||
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
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)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use crate::number::Number;
|
|
||||||
|
|
||||||
use super::Fraction;
|
use super::Fraction;
|
||||||
|
|
||||||
#[test]
|
#[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 {
|
pub fn pow(self, n: u32) -> Self {
|
||||||
let mut result = self.clone();
|
let mut result = self.clone();
|
||||||
if ((self.digits.len() * 8) as u32) < isize::BITS {
|
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 {
|
for _i in 1..n {
|
||||||
result = result * number;
|
result = result * number;
|
||||||
}
|
}
|
||||||
@ -127,7 +127,7 @@ impl Number {
|
|||||||
pub fn fact(self) -> Self {
|
pub fn fact(self) -> Self {
|
||||||
let mut fact = Number::from(1);
|
let mut fact = Number::from(1);
|
||||||
if ((self.digits.len() * 8) as u32) < isize::BITS {
|
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 {
|
for n in 1..=max {
|
||||||
fact = fact * n;
|
fact = fact * n;
|
||||||
}
|
}
|
||||||
@ -213,13 +213,19 @@ impl Number {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Number> for isize {
|
impl TryFrom<Number> for isize {
|
||||||
fn from(value: Number) -> Self {
|
type Error = Box<dyn Error>;
|
||||||
|
|
||||||
|
fn try_from(value: Number) -> Result<Self, Self::Error> {
|
||||||
let mut num = 0;
|
let mut num = 0;
|
||||||
for (pos, &digit) in value.digits.iter().rev().enumerate() {
|
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
|
num += mul.unwrap();
|
||||||
|
}
|
||||||
|
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)]
|
#[cfg(test)]
|
||||||
mod number_tests {
|
mod number_tests {
|
||||||
use crate::number::{Number, Sign};
|
use crate::number::{Number, Sign};
|
||||||
@ -450,4 +501,60 @@ mod number_tests {
|
|||||||
assert_eq!(digit_4, 2);
|
assert_eq!(digit_4, 2);
|
||||||
assert_eq!(digit_5, 1);
|
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