diff --git a/5kyu/some_egyptians_fractions/solution.rs b/5kyu/some_egyptians_fractions/solution.rs new file mode 100644 index 0000000..c46f663 --- /dev/null +++ b/5kyu/some_egyptians_fractions/solution.rs @@ -0,0 +1,66 @@ +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() +} diff --git a/README.md b/README.md index 0f52e5e..406f9dc 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,7 @@ - [Perimeter of squares in a rectangle](https://www.codewars.com/kata/559a28007caad2ac4e000083) - [solution](5kyu/perimeter_of_squares_in_a_rectangle) - [My smallest code interpreter (aka Brainf**k)](https://www.codewars.com/kata/526156943dfe7ce06200063e) - [solution](5kyu/my_smallest_code_interpreter_bf) - [Count IP Addresses](https://www.codewars.com/kata/526989a41034285187000de4) - [solution](5kyu/count_ip_addresses) +- [Some Egyptian fractions](https://www.codewars.com/kata/54f8693ea58bce689100065f) - [solution](5kyu/some_egyptians_fractions) ### C