use std::ops::{Div, Mul, Rem};
pub trait Euclidean<T>
where
T: Copy + Ord + Mul<Output = Self> + Div<Output = Self> + Rem<Output = Self> + Default,
Self: std::marker::Sized,
{
fn gcd(x: T, y: T) -> T;
fn lcm(x: T, y: T) -> Self;
}
impl<T> Euclidean<T> for T
where
T: Copy + Ord + Mul<Output = Self> + Div<Output = Self> + Rem<Output = Self> + Default,
Self: std::marker::Sized,
{
fn gcd(mut x: T, mut y: T) -> T {
while x != T::default() {
if x < y {
std::mem::swap(&mut x, &mut y);
}
x = x % y;
}
y
}
fn lcm(x: T, y: T) -> T {
let gcd = Self::gcd(x, y);
x * y / gcd
}
}