mirror of
https://gitlab.com/mfocko/CodeWars.git
synced 2024-11-09 11:09:07 +01:00
67 lines
1.3 KiB
Rust
67 lines
1.3 KiB
Rust
|
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()
|
||
|
}
|