competitive/num/
urational.rs

1use super::{Bounded, One, Unsigned, Zero};
2use std::{
3    cmp::Ordering,
4    fmt::{self, Debug},
5    ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign},
6};
7
8#[derive(Clone, Copy)]
9pub struct URational<T>
10where
11    T: Unsigned,
12{
13    pub num: T,
14    pub den: T,
15}
16
17impl<T> PartialEq for URational<T>
18where
19    T: Unsigned,
20{
21    fn eq(&self, other: &Self) -> bool {
22        self.num == other.num && self.den == other.den
23    }
24}
25
26impl<T> Eq for URational<T> where T: Unsigned {}
27
28impl<T> PartialOrd for URational<T>
29where
30    T: Unsigned,
31{
32    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
33        Some(self.cmp(other))
34    }
35}
36
37impl<T> Ord for URational<T>
38where
39    T: Unsigned,
40{
41    fn cmp(&self, other: &Self) -> Ordering {
42        match (self.den.is_zero(), other.den.is_zero()) {
43            (true, true) => self.num.cmp(&other.num),
44            (true, false) => self.num.cmp(&T::zero()),
45            (false, true) => T::zero().cmp(&other.num),
46            (false, false) => (self.num * other.den).cmp(&(self.den * other.num)),
47        }
48    }
49}
50
51impl<T> Debug for URational<T>
52where
53    T: Unsigned + Debug,
54{
55    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56        write!(f, "{:?}/{:?}", self.num, self.den)
57    }
58}
59
60impl<T> URational<T>
61where
62    T: Unsigned,
63{
64    pub fn new(num: T, den: T) -> Self {
65        let g = num.gcd(den);
66        Self::new_unchecked(num / g, den / g)
67    }
68    pub fn new_unchecked(num: T, den: T) -> Self {
69        Self { num, den }
70    }
71    pub fn eval(self) -> T {
72        self.num / self.den
73    }
74    pub fn map<U>(self, mut f: impl FnMut(T) -> U) -> URational<U>
75    where
76        U: Unsigned,
77    {
78        URational::new(f(self.num), f(self.den))
79    }
80    pub fn map_unchecked<U>(self, mut f: impl FnMut(T) -> U) -> URational<U>
81    where
82        U: Unsigned,
83    {
84        URational::new_unchecked(f(self.num), f(self.den))
85    }
86    pub fn map_eval<U>(self, mut f: impl FnMut(T) -> U) -> <U as Div>::Output
87    where
88        U: Div,
89    {
90        f(self.num) / f(self.den)
91    }
92}
93
94impl<T> Bounded for URational<T>
95where
96    T: Unsigned,
97{
98    fn maximum() -> Self {
99        Self::new_unchecked(T::one(), T::zero())
100    }
101    fn minimum() -> Self {
102        Self::zero()
103    }
104}
105
106impl<T> Zero for URational<T>
107where
108    T: Unsigned,
109{
110    fn zero() -> Self {
111        Self::new_unchecked(T::zero(), T::one())
112    }
113}
114impl<T> One for URational<T>
115where
116    T: Unsigned,
117{
118    fn one() -> Self {
119        Self::new_unchecked(T::one(), T::one())
120    }
121}
122
123impl<T> Add for URational<T>
124where
125    T: Unsigned,
126{
127    type Output = Self;
128    fn add(self, rhs: Self) -> Self::Output {
129        Self::new(self.num * rhs.den + self.den * rhs.num, self.den * rhs.den)
130    }
131}
132impl<T> Sub for URational<T>
133where
134    T: Unsigned,
135{
136    type Output = Self;
137    fn sub(self, rhs: Self) -> Self::Output {
138        Self::new(self.num * rhs.den - self.den * rhs.num, self.den * rhs.den)
139    }
140}
141impl<T> Mul for URational<T>
142where
143    T: Unsigned,
144{
145    type Output = Self;
146    fn mul(self, rhs: Self) -> Self::Output {
147        Self::new(self.num * rhs.num, self.den * rhs.den)
148    }
149}
150impl<T> Div for URational<T>
151where
152    T: Unsigned,
153{
154    type Output = Self;
155    fn div(self, rhs: Self) -> Self::Output {
156        Self::new(self.num * rhs.den, self.den * rhs.num)
157    }
158}
159impl<T> AddAssign for URational<T>
160where
161    T: Unsigned,
162{
163    fn add_assign(&mut self, rhs: Self) {
164        *self = *self + rhs;
165    }
166}
167impl<T> SubAssign for URational<T>
168where
169    T: Unsigned,
170{
171    fn sub_assign(&mut self, rhs: Self) {
172        *self = *self - rhs;
173    }
174}
175impl<T> MulAssign for URational<T>
176where
177    T: Unsigned,
178{
179    fn mul_assign(&mut self, rhs: Self) {
180        *self = *self * rhs;
181    }
182}
183impl<T> DivAssign for URational<T>
184where
185    T: Unsigned,
186{
187    fn div_assign(&mut self, rhs: Self) {
188        *self = *self / rhs;
189    }
190}