diff --git a/src/es02_rational.rs b/src/es02_rational.rs new file mode 100644 index 0000000..7cdcdec --- /dev/null +++ b/src/es02_rational.rs @@ -0,0 +1,58 @@ +#![allow(dead_code)] + +/** Es.2 + * Si definisca un modulo razionali che contiene una implementazione dei numeri razionali, + * cioe’ una struttura Razionali con i due campi interi num e denum (per numeratore e denominatore) + * i metodi di somma, prodotto, e riduzione ai minimi termini (dividere num e denum per il massimo comun divisore) + * le funzioni new che ritorna un Razionale (con 2 parametri) e int_to_raz che prende un intero + * e ritorna il numero razionale che ha quell’intero come numeratore e 1 come denominatore. + */ + +#[derive(Debug, PartialEq, Clone)] +pub struct Rational { + num: i32, + den: i32, +} + +impl Rational { + pub fn new(num: i32, den: i32) -> Self { + assert!(den != 0, "Cannot divide by zero!"); + + let mut numero = Rational { num, den }; + numero.reduce(); + numero + } + pub fn from(int: i32) -> Self { + Rational { num: int, den: 1 } + } + + pub fn multiplication(&mut self, other: &Rational) -> &mut Self { + self.num *= other.num; + self.den *= other.den; + self.reduce() + } + pub fn addition(&mut self, other: &Rational) -> &mut Self { + self.num = (self.num * other.den) + (other.num * self.den); + self.den *= other.den; + self.reduce() + } + fn reduce(&mut self) -> &mut Self { + if self.den < 0 { + self.num *= -1; + self.den *= -1; + } + + let mcd = Self::mcd(self.num, self.den); + self.num /= mcd; + self.den /= mcd; + self + } + fn mcd(a: i32, b: i32) -> i32 { + // mcd Euclideo https://en.wikipedia.org/wiki/Euclidean_algorithm#Implementations + if b == 0 { + a + } else { + Self::mcd(b, a % b) + } + } +} diff --git a/src/lib.rs b/src/lib.rs index 5015d3a..1cdcdf3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1 +1,2 @@ pub mod es01_anagram; +pub mod es02_rational; diff --git a/tests/es02_rational.rs b/tests/es02_rational.rs new file mode 100644 index 0000000..b28effb --- /dev/null +++ b/tests/es02_rational.rs @@ -0,0 +1,46 @@ +use esercizi::es02_rational::Rational; + +#[test] +fn test_razionali() { + assert_eq!( + Rational::new(2, 3).multiplication(&Rational::new(3, 2)), + &Rational::new(1, 1) + ); + assert_eq!( + Rational::new(4, 3).multiplication(&Rational::new(5, 7)), + &Rational::new(20, 21) + ); + assert_eq!( + Rational::new(-3, 2).multiplication(&Rational::new(7, 4)), + &Rational::new(-21, 8) + ); + assert_eq!( + Rational::new(-3, 2).multiplication(&Rational::new(14, 14)), + &Rational::new(-3, 2) + ); + assert_eq!( + Rational::new(2, 3).addition(&Rational::new(3, 2)), + &Rational::new(13, 6) + ); + assert_eq!( + Rational::new(5, 3).addition(&Rational::new(5, 2)), + &Rational::new(25, 6) + ); + assert_eq!( + Rational::new(-3, 16).addition(&Rational::new(5, -4)), + &Rational::new(-23, 16) + ); + assert_eq!( + Rational::from(100).addition(&Rational::from(47)), + &Rational::from(147) + ); + assert_eq!( + Rational::new(23, 12) + .addition(&Rational::new(24, 15)) + .addition(&Rational::new(23, 24)) + .addition(&Rational::new(-437, 120)), + &Rational::new(5, 6) + ); + assert_eq!(Rational::new(-2, 4), Rational::new(-1, 2)); + assert_eq!(Rational::new(4, -2), Rational::new(-2, 1)) +}