impl Solution {
fn to_frac(expr: &str) -> (i32, i32) {
let exprs: Vec<_> = expr.split('/').collect();
(exprs[0].parse::<i32>().unwrap(), exprs[1].parse::<i32>().unwrap())
}
fn gcd(mut a: i32, mut b: i32) -> i32 {
while b != 0 {
a %= b;
(a, b) = (b, a)
}
a
}
pub fn fraction_addition(expression: String) -> String {
let exprs_plus: Vec<_> = expression.split('+').collect();
let [mut nom, mut de_nom] = [0, 1];
for expr in exprs_plus {
let exprs_minus: Vec<_> = expr.split('-').collect();
let (mut a, mut b, i) = if exprs_minus[0].is_empty() {
let (a, b) = Self::to_frac(exprs_minus[1]);
(-a, b, 2)
} else {
let (a, b) = Self::to_frac(exprs_minus[0]);
(a, b, 1)
};
for expr in &exprs_minus[i..] {
let (c, d) = Self::to_frac(expr);
(a, b) = (a * d - b * c, b * d);
let g = Self::gcd(a, b);
(a, b) = (a / g, b / g);
}
(nom, de_nom) = (nom * b + a * de_nom, b * de_nom);
let g = Self::gcd(nom, de_nom);
(nom, de_nom) = (nom / g, de_nom / g);
}
if de_nom < 0 {
(nom, de_nom) = (-nom, -de_nom);
}
[nom.to_string(), "/".to_owned(), de_nom.to_string()].concat()
}
}