1use std::fmt::Debug;
4use std::iter::{Product, Sum};
5use std::ops::{
6 Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
7 Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
8};
9
10pub trait Number:
12 Copy
13 + Debug
14 + Default
15 + PartialEq
16 + PartialOrd
17 + Add<Output = Self>
18 + AddAssign
19 + Div<Output = Self>
20 + DivAssign
21 + Mul<Output = Self>
22 + MulAssign
23 + Rem<Output = Self>
24 + RemAssign
25 + Sub<Output = Self>
26 + SubAssign
27 + Sum<Self>
28 + for<'a> Sum<&'a Self>
29 + Product<Self>
30 + for<'a> Product<&'a Self>
31{
32 const ZERO: Self;
33 const ONE: Self;
34 const MIN: Self;
35 const MAX: Self;
36
37 #[must_use]
38 fn abs(self) -> Self;
39 #[must_use]
40 fn rem_euclid(self, rhs: Self) -> Self;
41}
42
43pub trait Signed: Number + Neg<Output = Self> + From<i8> {
45 const MINUS_ONE: Self;
46}
47
48pub trait Integer:
50 Number
51 + Not<Output = Self>
52 + BitAnd<Output = Self>
53 + BitAndAssign
54 + BitOr<Output = Self>
55 + BitOrAssign
56 + BitXor<Output = Self>
57 + BitXorAssign
58 + Shl<Output = Self>
59 + Shl<u32, Output = Self>
60 + ShlAssign
61 + ShlAssign<u32>
62 + Shr<Output = Self>
63 + Shr<u32, Output = Self>
64 + ShrAssign
65 + ShrAssign<u32>
66 + TryInto<i128>
67{
68 type Unsigned: UnsignedInteger;
69 type Signed: SignedInteger;
70
71 #[must_use]
72 fn abs_diff(self, rhs: Self) -> Self::Unsigned;
73 #[must_use]
74 fn checked_add(self, rhs: Self) -> Option<Self>;
75 #[must_use]
76 fn checked_sub(self, rhs: Self) -> Option<Self>;
77 #[must_use]
78 fn checked_mul(self, rhs: Self) -> Option<Self>;
79 #[must_use]
80 fn trailing_ones(self) -> u32;
81 #[must_use]
82 fn trailing_zeros(self) -> u32;
83 #[must_use]
84 fn unsigned_abs(self) -> Self::Unsigned;
85}
86
87pub trait UnsignedInteger: Integer<Unsigned = Self> + From<u8> {
89 #[must_use]
90 fn wrapping_add_signed(self, rhs: Self::Signed) -> Self;
91}
92
93pub trait SignedInteger: Integer<Signed = Self> + Signed {}
95
96macro_rules! number_impl {
97 (int => $($u:ty: $s:ty ),+) => {
98 $(impl Number for $u {
99 const ZERO: Self = 0;
100 const ONE: Self = 1;
101 const MIN: Self = Self::MIN;
102 const MAX: Self = Self::MAX;
103
104 #[inline]
105 fn abs(self) -> Self {
106 self }
108
109 #[inline]
110 fn rem_euclid(self, rhs: Self) -> Self {
111 self.rem_euclid(rhs)
112 }
113 })+
114
115 $(impl Integer for $u {
116 type Unsigned = $u;
117 type Signed = $s;
118
119 #[inline]
120 fn abs_diff(self, rhs: Self) -> Self::Unsigned {
121 self.abs_diff(rhs)
122 }
123 #[inline]
124 fn checked_add(self, rhs: Self) -> Option<Self> {
125 self.checked_add(rhs)
126 }
127 #[inline]
128 fn checked_sub(self, rhs: Self) -> Option<Self> {
129 self.checked_sub(rhs)
130 }
131 #[inline]
132 fn checked_mul(self, rhs: Self) -> Option<Self> {
133 self.checked_mul(rhs)
134 }
135 #[inline]
136 fn trailing_ones(self) -> u32 {
137 self.trailing_ones()
138 }
139 #[inline]
140 fn trailing_zeros(self) -> u32 {
141 self.trailing_zeros()
142 }
143 #[inline]
144 fn unsigned_abs(self) -> Self::Unsigned {
145 self }
147 })+
148
149 $(impl UnsignedInteger for $u {
150 #[inline]
151 fn wrapping_add_signed(self, rhs: Self::Signed) -> Self {
152 self.wrapping_add_signed(rhs)
153 }
154 })+
155
156 $(impl Number for $s {
157 const ZERO: Self = 0;
158 const ONE: Self = 1;
159 const MIN: Self = Self::MIN;
160 const MAX: Self = Self::MAX;
161
162 #[inline]
163 fn abs(self) -> Self {
164 self.abs()
165 }
166
167 #[inline]
168 fn rem_euclid(self, rhs: Self) -> Self {
169 self.rem_euclid(rhs)
170 }
171 })+
172
173 $(impl Signed for $s {
174 const MINUS_ONE: Self = -Self::ONE;
175 })+
176
177 $(impl Integer for $s {
178 type Unsigned = $u;
179 type Signed = $s;
180
181 #[inline]
182 fn abs_diff(self, rhs: Self) -> Self::Unsigned {
183 self.abs_diff(rhs)
184 }
185 #[inline]
186 fn checked_add(self, rhs: Self) -> Option<Self> {
187 self.checked_add(rhs)
188 }
189 #[inline]
190 fn checked_sub(self, rhs: Self) -> Option<Self> {
191 self.checked_sub(rhs)
192 }
193 #[inline]
194 fn checked_mul(self, rhs: Self) -> Option<Self> {
195 self.checked_mul(rhs)
196 }
197 #[inline]
198 fn trailing_ones(self) -> u32 {
199 self.trailing_ones()
200 }
201 #[inline]
202 fn trailing_zeros(self) -> u32 {
203 self.trailing_zeros()
204 }
205 #[inline]
206 fn unsigned_abs(self) -> Self::Unsigned {
207 self.unsigned_abs()
208 }
209 })+
210
211 $(impl SignedInteger for $s {})+
212 };
213 (float => $($t:ty),+) => {$(
214 impl Number for $t {
215 const ZERO: Self = 0.0;
216 const ONE: Self = 1.0;
217 const MIN: Self = Self::NEG_INFINITY;
218 const MAX: Self = Self::INFINITY;
219
220 #[inline]
221 fn abs(self) -> Self {
222 self.abs()
223 }
224
225 #[inline]
226 fn rem_euclid(self, rhs: Self) -> Self {
227 self.rem_euclid(rhs)
228 }
229 }
230
231 impl Signed for $t {
232 const MINUS_ONE: Self = -Self::ONE;
233 }
234 )+};
235}
236number_impl! {int => u8: i8, u16: i16, u32: i32, u64: i64, u128: i128, usize: isize}
237number_impl! {float => f32, f64}
238
239#[inline]
251pub fn is_prime<T: UnsignedInteger>(n: T) -> bool {
252 if n <= T::ONE {
253 return false;
254 }
255 if n == T::from(2) || n == T::from(3) {
256 return true;
257 }
258 if n % T::from(2) == T::ZERO || n % T::from(3) == T::ZERO {
259 return false;
260 }
261
262 let mut i = T::from(5);
263 while let Some(square) = i.checked_mul(i) {
264 if square > n {
265 break;
266 }
267
268 if n % i == T::ZERO || n % (i + T::from(2)) == T::ZERO {
269 return false;
270 }
271
272 if let Some(next) = i.checked_add(T::from(6)) {
273 i = next;
274 } else {
275 break;
276 }
277 }
278
279 true
280}
281
282#[inline]
296pub fn egcd<T: SignedInteger>(mut a: T, mut b: T) -> (T, T, T) {
297 let (mut x0, mut x1, mut y0, mut y1) = (T::ONE, T::ZERO, T::ZERO, T::ONE);
298
299 while b != T::ZERO {
300 let q = a / b;
301 (a, b) = (b, a % b);
302 (x0, x1) = (x1, x0 - q * x1);
303 (y0, y1) = (y1, y0 - q * y1);
304 }
305
306 (a, x0, y0)
307}
308
309pub fn lcm<T: SignedInteger>(a: T, b: T) -> T {
318 if a == T::ZERO || b == T::ZERO {
319 return T::ZERO;
320 }
321
322 let (gcd, ..) = egcd(a, b);
323 (a / gcd).abs() * b.abs()
324}
325
326#[inline]
340pub fn mod_inverse<T: SignedInteger>(a: T, b: T) -> Option<T> {
341 let (gcd, x, _) = egcd(a, b);
342 if gcd == T::ONE {
343 Some(x.rem_euclid(b))
344 } else {
345 None
346 }
347}
348
349#[inline]
363pub fn chinese_remainder<T: SignedInteger>(
364 residues: impl IntoIterator<Item = T>,
365 moduli: impl IntoIterator<Item = T, IntoIter: Clone>,
366) -> Option<T> {
367 let moduli = moduli.into_iter();
368 let product = moduli.clone().product();
369
370 let mut sum = T::ZERO;
371 for (residue, modulus) in residues.into_iter().zip(moduli) {
372 let p = product / modulus;
373 sum += residue * mod_inverse(p, modulus)? * p;
374 }
375
376 Some(sum.rem_euclid(product))
377}
378
379#[inline]
388pub fn mod_pow<T: UnsignedInteger>(base: T, exponent: T, modulus: T) -> T {
389 let mut result = T::ONE;
390 let mut base = base % modulus;
391 let mut exponent = exponent;
392
393 while exponent > T::ZERO {
394 if exponent % T::from(2) == T::ONE {
395 result = (result * base) % modulus;
396 }
397 exponent >>= 1;
398 base = (base * base) % modulus;
399 }
400
401 result
402}