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 #[must_use]
42 fn squared_diff(self, rhs: Self) -> Self;
43}
44
45pub trait Signed: Number + Neg<Output = Self> + From<i8> {
47 const MINUS_ONE: Self;
48}
49
50pub trait Integer:
52 Number
53 + Not<Output = Self>
54 + BitAnd<Output = Self>
55 + BitAndAssign
56 + BitOr<Output = Self>
57 + BitOrAssign
58 + BitXor<Output = Self>
59 + BitXorAssign
60 + Shl<Output = Self>
61 + Shl<u32, Output = Self>
62 + ShlAssign
63 + ShlAssign<u32>
64 + Shr<Output = Self>
65 + Shr<u32, Output = Self>
66 + ShrAssign
67 + ShrAssign<u32>
68 + TryInto<i128>
69{
70 type NonZero: Copy + TryFrom<Self> + Into<Self>;
71 type Unsigned: UnsignedInteger;
72 type Signed: SignedInteger;
73
74 #[must_use]
75 fn abs_diff(self, rhs: Self) -> Self::Unsigned;
76 #[must_use]
77 fn checked_add(self, rhs: Self) -> Option<Self>;
78 #[must_use]
79 fn checked_sub(self, rhs: Self) -> Option<Self>;
80 #[must_use]
81 fn checked_mul(self, rhs: Self) -> Option<Self>;
82 #[must_use]
83 fn isolate_lowest_one(self) -> Self;
84 #[must_use]
85 fn lowest_one(self) -> Option<u32>;
86 #[must_use]
87 fn trailing_ones(self) -> u32;
88 #[must_use]
89 fn trailing_zeros(self) -> u32;
90 #[must_use]
91 fn unsigned_abs(self) -> Self::Unsigned;
92 #[must_use]
93 fn saturating_sub_0(self, rhs: Self) -> Self::Unsigned;
94}
95
96pub trait UnsignedInteger: Integer<Unsigned = Self> + From<u8> {
98 #[must_use]
99 fn wrapping_add_signed(self, rhs: Self::Signed) -> Self;
100}
101
102pub trait SignedInteger: Integer<Signed = Self> + Signed {}
104
105macro_rules! number_impl {
106 (int => $($u:ident: $s:ident ),+) => {
107 $(impl Number for $u {
108 const ZERO: Self = 0;
109 const ONE: Self = 1;
110 const MIN: Self = Self::MIN;
111 const MAX: Self = Self::MAX;
112
113 #[inline]
114 fn abs(self) -> Self {
115 self }
117
118 #[inline]
119 fn rem_euclid(self, rhs: Self) -> Self {
120 self.rem_euclid(rhs)
121 }
122
123 #[inline]
124 fn squared_diff(self, rhs: Self) -> Self {
125 let diff = self.abs_diff(rhs);
126 diff * diff
127 }
128 })+
129
130 $(impl Integer for $u {
131 type NonZero = std::num::NonZero<$u>;
132 type Unsigned = $u;
133 type Signed = $s;
134
135 #[inline]
136 fn abs_diff(self, rhs: Self) -> Self::Unsigned {
137 self.abs_diff(rhs)
138 }
139 #[inline]
140 fn checked_add(self, rhs: Self) -> Option<Self> {
141 self.checked_add(rhs)
142 }
143 #[inline]
144 fn checked_sub(self, rhs: Self) -> Option<Self> {
145 self.checked_sub(rhs)
146 }
147 #[inline]
148 fn checked_mul(self, rhs: Self) -> Option<Self> {
149 self.checked_mul(rhs)
150 }
151 #[inline]
152 fn isolate_lowest_one(self) -> Self {
153 self.isolate_lowest_one()
154 }
155 #[inline]
156 fn lowest_one(self) -> Option<u32> {
157 self.lowest_one()
158 }
159 #[inline]
160 fn trailing_ones(self) -> u32 {
161 self.trailing_ones()
162 }
163 #[inline]
164 fn trailing_zeros(self) -> u32 {
165 self.trailing_zeros()
166 }
167 #[inline]
168 fn unsigned_abs(self) -> Self::Unsigned {
169 self }
171 #[inline]
172 fn saturating_sub_0(self, rhs: Self) -> Self::Unsigned {
173 self.saturating_sub(rhs)
174 }
175 })+
176
177 $(impl UnsignedInteger for $u {
178 #[inline]
179 fn wrapping_add_signed(self, rhs: Self::Signed) -> Self {
180 self.wrapping_add_signed(rhs)
181 }
182 })+
183
184 $(impl Number for $s {
185 const ZERO: Self = 0;
186 const ONE: Self = 1;
187 const MIN: Self = Self::MIN;
188 const MAX: Self = Self::MAX;
189
190 #[inline]
191 fn abs(self) -> Self {
192 self.abs()
193 }
194
195 #[inline]
196 fn rem_euclid(self, rhs: Self) -> Self {
197 self.rem_euclid(rhs)
198 }
199
200 #[inline]
201 fn squared_diff(self, rhs: Self) -> Self {
202 let diff = self - rhs;
203 diff * diff
204 }
205 })+
206
207 $(impl Signed for $s {
208 const MINUS_ONE: Self = -Self::ONE;
209 })+
210
211 $(impl Integer for $s {
212 type NonZero = std::num::NonZero<$s>;
213 type Unsigned = $u;
214 type Signed = $s;
215
216 #[inline]
217 fn abs_diff(self, rhs: Self) -> Self::Unsigned {
218 self.abs_diff(rhs)
219 }
220 #[inline]
221 fn checked_add(self, rhs: Self) -> Option<Self> {
222 self.checked_add(rhs)
223 }
224 #[inline]
225 fn checked_sub(self, rhs: Self) -> Option<Self> {
226 self.checked_sub(rhs)
227 }
228 #[inline]
229 fn checked_mul(self, rhs: Self) -> Option<Self> {
230 self.checked_mul(rhs)
231 }
232 #[inline]
233 fn isolate_lowest_one(self) -> Self {
234 self.isolate_lowest_one()
235 }
236 #[inline]
237 fn lowest_one(self) -> Option<u32> {
238 self.lowest_one()
239 }
240 #[inline]
241 fn trailing_ones(self) -> u32 {
242 self.trailing_ones()
243 }
244 #[inline]
245 fn trailing_zeros(self) -> u32 {
246 self.trailing_zeros()
247 }
248 #[inline]
249 fn unsigned_abs(self) -> Self::Unsigned {
250 self.unsigned_abs()
251 }
252 #[inline]
253 #[expect(clippy::cast_sign_loss)]
254 fn saturating_sub_0(self, rhs: Self) -> Self::Unsigned {
255 let diff = (self as $u).wrapping_sub(rhs as $u);
258 let mask = (0 as $u).wrapping_sub($u::from(self >= rhs));
259 diff & mask
260 }
261 })+
262
263 $(impl SignedInteger for $s {})+
264 };
265 (float => $($t:ident),+) => {$(
266 impl Number for $t {
267 const ZERO: Self = 0.0;
268 const ONE: Self = 1.0;
269 const MIN: Self = Self::NEG_INFINITY;
270 const MAX: Self = Self::INFINITY;
271
272 #[inline]
273 fn abs(self) -> Self {
274 self.abs()
275 }
276
277 #[inline]
278 fn rem_euclid(self, rhs: Self) -> Self {
279 self.rem_euclid(rhs)
280 }
281
282 #[inline]
283 fn squared_diff(self, rhs: Self) -> Self {
284 let diff = self - rhs;
285 diff * diff
286 }
287 }
288
289 impl Signed for $t {
290 const MINUS_ONE: Self = -Self::ONE;
291 }
292 )+};
293}
294number_impl! {int => u8: i8, u16: i16, u32: i32, u64: i64, u128: i128, usize: isize}
295number_impl! {float => f32, f64}
296
297#[inline]
309#[must_use]
310pub fn is_prime<T: UnsignedInteger>(n: T) -> bool {
311 if n <= T::ONE {
312 return false;
313 }
314 if n == T::from(2) || n == T::from(3) {
315 return true;
316 }
317 if n % T::from(2) == T::ZERO || n % T::from(3) == T::ZERO {
318 return false;
319 }
320
321 let mut i = T::from(5);
322 while let Some(square) = i.checked_mul(i)
323 && square <= n
324 {
325 if n % i == T::ZERO || n % (i + T::from(2)) == T::ZERO {
326 return false;
327 }
328
329 if let Some(next) = i.checked_add(T::from(6)) {
330 i = next;
331 } else {
332 break;
333 }
334 }
335
336 true
337}
338
339#[inline]
353#[must_use]
354pub fn sum_of_divisors<T: UnsignedInteger>(n: T) -> Option<T> {
355 if n <= T::ONE {
356 return Some(n);
357 }
358
359 let mut sum = T::ZERO;
360 let mut d = T::ONE;
361 while let Some(square) = d.checked_mul(d)
362 && square <= n
363 {
364 if n % d == T::ZERO {
365 sum = sum.checked_add(d)?;
366
367 let q = n / d;
368 if q != d {
369 sum = sum.checked_add(q)?;
370 }
371 }
372
373 d += T::ONE;
374 }
375
376 Some(sum)
377}
378
379#[inline]
388#[must_use]
389pub fn gcd<T: Integer>(mut a: T, mut b: T) -> T {
390 while b != T::ZERO {
391 (a, b) = (b, a % b);
392 }
393 a
394}
395
396#[inline]
410#[must_use]
411pub fn egcd<T: SignedInteger>(mut a: T, mut b: T) -> (T, T, T) {
412 let (mut x0, mut x1, mut y0, mut y1) = (T::ONE, T::ZERO, T::ZERO, T::ONE);
413
414 while b != T::ZERO {
415 let q = a / b;
416 (a, b) = (b, a % b);
417 (x0, x1) = (x1, x0 - q * x1);
418 (y0, y1) = (y1, y0 - q * y1);
419 }
420
421 (a, x0, y0)
422}
423
424#[inline]
433#[must_use]
434pub fn lcm<T: Integer>(a: T, b: T) -> T {
435 if a == T::ZERO || b == T::ZERO {
436 return T::ZERO;
437 }
438
439 (a / gcd(a, b)).abs() * b.abs()
440}
441
442#[inline]
456#[must_use]
457pub fn mod_inverse<T: SignedInteger>(a: T, b: T) -> Option<T> {
458 let (gcd, x, _) = egcd(a, b);
459 if gcd == T::ONE {
460 Some(x.rem_euclid(b))
461 } else {
462 None
463 }
464}
465
466#[inline]
480#[must_use]
481pub fn chinese_remainder<T: SignedInteger>(
482 residues: impl IntoIterator<Item = T>,
483 moduli: impl IntoIterator<Item = T, IntoIter: Clone>,
484) -> Option<T> {
485 let moduli = moduli.into_iter();
486 let product = moduli.clone().product();
487
488 let mut sum = T::ZERO;
489 for (residue, modulus) in residues.into_iter().zip(moduli) {
490 let p = product / modulus;
491 sum += residue * mod_inverse(p, modulus)? * p;
492 }
493
494 Some(sum.rem_euclid(product))
495}
496
497#[inline]
506#[must_use]
507pub fn mod_pow<T: UnsignedInteger>(base: T, exponent: T, modulus: T) -> T {
508 let mut result = T::ONE;
509 let mut base = base % modulus;
510 let mut exponent = exponent;
511
512 while exponent > T::ZERO {
513 if exponent % T::from(2) == T::ONE {
514 result = (result * base) % modulus;
515 }
516 exponent >>= 1;
517 base = (base * base) % modulus;
518 }
519
520 result
521}