use std::cmp::max; use std::cmp::min; fn gcd(mut a: u32, mut b: u32) -> u32 { while b != 0 { let t = b; b = a % b; a = t; } a } fn lcm(a: u32, b: u32) -> u32 { let c = gcd(a, b); max(a, b) / c * min(a, b) } fn format_fraction(fraction: &(u32, u32)) -> String { if fraction.1 == 1 { return format!("{}", fraction.0); } format!("{}/{}", fraction.0, fraction.1) } fn decompose(mut num: u32, mut denom: u32) -> String { if num == 0 { return "".to_string(); } let mut fractions: Vec<(u32, u32)> = Vec::new(); if num >= denom { fractions.push((num / denom, 1)); num = num % denom; } let mut running_denom = 2; while num > 1 { if num * running_denom < denom { running_denom += 1; continue; } fractions.push((1, running_denom)); let new_denom = lcm(denom, running_denom); let new_num = (new_denom / denom) * num - new_denom / running_denom; num = new_num; denom = new_denom; running_denom += 1; } if num >= 1 { fractions.push((num, denom)); } fractions .iter() .map(format_fraction) .reduce(|acc, frac| acc + ", " + &frac) .unwrap() }