1use crate::num::arithmetic::mod_pow::mul_mod_helper;
16use crate::num::arithmetic::sqrt::{sqrt_rem_2_newton, sqrt_rem_newton};
17use crate::num::arithmetic::traits::{
18 DivMod, FloorRoot, FloorSqrt, Gcd, ModMulPrecomputed, ModSub, ModSubAssign, Parity, PowerOf2,
19 SqrtRem, Square, WrappingAddAssign, WrappingMulAssign, WrappingSquare, WrappingSubAssign,
20 XMulYToZZ, XXDivModYToQR, XXSubYYToZZ,
21};
22use crate::num::basic::integers::{PrimitiveInt, USIZE_IS_U32};
23use crate::num::basic::unsigneds::PrimitiveUnsigned;
24use crate::num::conversion::traits::{ExactFrom, WrappingFrom};
25use crate::num::factorization::primes::SMALL_PRIMES;
26use crate::num::factorization::traits::{Factor, IsPrime, IsSquare, Primes};
27use crate::num::logic::traits::{LeadingZeros, LowMask, SignificantBits};
28use core::mem::swap;
29
30pub(crate) const MAX_FACTORS_IN_U8: usize = 4;
31pub(crate) const MAX_FACTORS_IN_U16: usize = 6;
32pub(crate) const MAX_FACTORS_IN_U32: usize = 9;
33pub(crate) const MAX_FACTORS_IN_U64: usize = 15;
34pub(crate) const MAX_FACTORS_IN_USIZE: usize = 15;
35
36#[derive(Clone, Debug, Eq, PartialEq)]
39pub struct Factors<T: PrimitiveUnsigned, const N: usize> {
40 factors: [T; N],
41 exponents: [u8; N],
42}
43
44#[derive(Clone, Debug, Eq, PartialEq)]
46pub struct FactorsIterator<T: PrimitiveUnsigned, const N: usize> {
47 i: usize,
48 factors: Factors<T, N>,
49}
50
51impl<T: PrimitiveUnsigned, const N: usize> Iterator for FactorsIterator<T, N> {
52 type Item = (T, u8);
53
54 fn next(&mut self) -> Option<(T, u8)> {
55 let e = *self.factors.exponents.get(self.i)?;
56 if e == 0 {
57 return None;
58 }
59 let f = self.factors.factors[self.i];
60 self.i += 1;
61 Some((f, e))
62 }
63}
64
65impl<T: PrimitiveUnsigned, const N: usize> IntoIterator for Factors<T, N> {
66 type IntoIter = FactorsIterator<T, N>;
67 type Item = (T, u8);
68
69 fn into_iter(self) -> FactorsIterator<T, N> {
70 FactorsIterator {
71 i: 0,
72 factors: self,
73 }
74 }
75}
76
77impl<T: PrimitiveUnsigned, const N: usize> Factors<T, N> {
78 const fn new() -> Self {
79 Self {
80 factors: [T::ZERO; N],
81 exponents: [0; N],
82 }
83 }
84
85 fn insert(&mut self, factor: T, exp: u8) {
91 let mut inserting = false;
92 let mut previous_f = T::ZERO;
93 let mut previous_e = 0;
94 for (f, e) in self.factors.iter_mut().zip(self.exponents.iter_mut()) {
95 if inserting {
96 swap(&mut previous_f, f);
97 swap(&mut previous_e, e);
98 if previous_e == 0 {
99 break;
100 }
101 } else if *e == 0 {
102 *f = factor;
103 *e = exp;
104 break;
105 } else if *f == factor {
106 *e += exp;
107 break;
108 } else if *f > factor {
109 previous_f = *f;
110 previous_e = *e;
111 *f = factor;
112 *e = exp;
113 inserting = true;
114 }
115 }
116 }
117}
118
119type FactorsU8 = Factors<u8, MAX_FACTORS_IN_U8>;
120type FactorsU16 = Factors<u16, MAX_FACTORS_IN_U16>;
121type FactorsU32 = Factors<u32, MAX_FACTORS_IN_U32>;
122type FactorsU64 = Factors<u64, MAX_FACTORS_IN_U64>;
123type FactorsUsize = Factors<usize, MAX_FACTORS_IN_USIZE>;
124
125fn div_rem_precomputed_float_for_u32_factorization(a: u32, n: u32, inverse: f64) -> (u32, u32) {
128 let mut q = (f64::from(a) * inverse) as u32;
129 let r = a.wrapping_sub(q * n);
130 let ri = i32::wrapping_from(r);
131 if ri >= i32::wrapping_from(n) {
132 q += (f64::from(ri) * inverse) as u32;
133 (q + 1, a.wrapping_sub(q * n).wrapping_sub(n))
134 } else {
135 (q, r)
136 }
137}
138
139fn div_rem_precomputed_float_u64(a: u64, n: u64, npre: f64) -> (u64, u64) {
142 if a < n {
143 return (0, a);
144 }
145 if n.get_highest_bit() {
146 return (1, a.wrapping_sub(n));
147 }
148 let (mut q, r) = if n == 1 {
149 (a, 0)
150 } else {
151 let q = ((a as f64) * npre) as u64;
152 (q, a.wrapping_sub(q.wrapping_mul(n)))
153 };
154 let ri = i64::wrapping_from(r);
155 let ni = i64::wrapping_from(n);
156 if ri < ni.wrapping_neg() {
157 q -= ((-(ri as f64)) * npre) as u64;
158 } else if ri >= ni {
159 q += ((ri as f64) * npre) as u64;
160 } else if ri < 0 {
161 return (q - 1, r.wrapping_add(n));
162 } else {
163 return (q, r);
164 }
165 let r = a.wrapping_sub(q.wrapping_mul(n));
166 let ri = i64::wrapping_from(r);
167 if ri >= ni {
168 (q + 1, r.wrapping_sub(n))
169 } else if ri < 0 {
170 (q - 1, r.wrapping_add(n))
171 } else {
172 (q, r)
173 }
174}
175
176fn remove_factor_precomputed_float_u32(mut n: u32, p: u32, inverse: f64) -> (u32, u8) {
179 if p == 2 {
180 let exp = n.trailing_zeros();
181 if exp != 0 {
182 n >>= exp;
183 }
184 (n, u8::wrapping_from(exp))
185 } else {
186 let mut exp = 0;
187 while n >= p {
188 let (q, r) = div_rem_precomputed_float_for_u32_factorization(n, p, inverse);
189 if r != 0 {
190 break;
191 }
192 exp += 1;
193 n = q;
194 }
195 (n, exp)
196 }
197}
198
199fn remove_factor_precomputed_float_u64(mut n: u64, p: u64, inverse: f64) -> (u64, u8) {
202 if p == 2 {
203 let exp = u64::from(n.trailing_zeros());
204 if exp != 0 {
205 n >>= exp;
206 }
207 (n, u8::wrapping_from(exp))
208 } else {
209 let mut exp = 0;
210 while n >= p {
211 let (q, r) = div_rem_precomputed_float_u64(n, p, inverse);
212 if r != 0 {
213 break;
214 }
215 exp += 1;
216 n = q;
217 }
218 (n, exp)
219 }
220}
221
222fn factor_trial_range_u32(factors: &mut FactorsU32, mut n: u32, num_primes: usize) -> u32 {
225 for p in u32::primes().take(num_primes) {
226 if p.square() > n {
227 break;
228 }
229 let exp;
230 (n, exp) = remove_factor_precomputed_float_u32(n, p, 1.0 / f64::from(p));
231 if exp != 0 {
232 factors.insert(p, exp);
233 }
234 }
235 n
236}
237
238fn factor_trial_range_u64(factors: &mut FactorsU64, mut n: u64, num_primes: usize) -> u64 {
240 for p in u64::primes().take(num_primes) {
241 if p.square() > n {
242 break;
243 }
244 let exp;
245 (n, exp) = remove_factor_precomputed_float_u64(n, p, 1.0 / (p as f64));
246 if exp != 0 {
247 factors.insert(p, exp);
248 }
249 }
250 n
251}
252
253const POWER235_MOD63: [u8; 63] = [
254 7, 7, 4, 0, 5, 4, 0, 5, 6, 5, 4, 4, 0, 4, 4, 0, 5, 4, 5, 4, 4, 0, 5, 4, 0, 5, 4, 6, 7, 4, 0, 4,
255 4, 0, 4, 6, 7, 5, 4, 0, 4, 4, 0, 5, 4, 4, 5, 4, 0, 5, 4, 0, 4, 4, 4, 6, 4, 0, 5, 4, 0, 4, 6,
256];
257const POWER235_MOD61: [u8; 61] = [
258 7, 7, 0, 3, 1, 1, 0, 0, 2, 3, 0, 6, 1, 5, 5, 1, 1, 0, 0, 1, 3, 4, 1, 2, 2, 1, 0, 3, 2, 4, 0, 0,
259 4, 2, 3, 0, 1, 2, 2, 1, 4, 3, 1, 0, 0, 1, 1, 5, 5, 1, 6, 0, 3, 2, 0, 0, 1, 1, 3, 0, 7,
260];
261const POWER235_MOD44: [u8; 44] = [
262 7, 7, 0, 2, 3, 3, 0, 2, 2, 3, 0, 6, 7, 2, 0, 2, 3, 2, 0, 2, 3, 6, 0, 6, 2, 3, 0, 2, 2, 2, 0, 2,
263 6, 7, 0, 2, 3, 3, 0, 2, 2, 2, 0, 6,
264];
265const POWER235_MOD31: [u8; 31] =
266 [7, 7, 3, 0, 3, 5, 4, 1, 3, 1, 1, 0, 0, 0, 1, 2, 3, 0, 1, 1, 1, 0, 0, 2, 0, 5, 4, 2, 1, 2, 6];
267
268fn factor_square_u32(n: u32) -> (u32, u8) {
272 let mut t = POWER235_MOD31[(n % 31) as usize];
273 if t == 0 {
274 return (0, 0);
275 };
276 t &= POWER235_MOD44[(n % 44) as usize];
277 if t == 0 {
278 return (0, 0);
279 };
280 t &= POWER235_MOD61[(n % 61) as usize];
281 if t == 0 {
282 return (0, 0);
283 };
284 t &= POWER235_MOD63[(n % 63) as usize];
285 if t.odd() {
286 let (y, r) = n.sqrt_rem();
287 if r == 0 {
288 return (y, 2);
289 }
290 }
291 (0, 0)
292}
293
294fn factor_power23_u64(n: u64) -> (u64, u8) {
298 let mut t = POWER235_MOD31[(n % 31) as usize];
299 if t == 0 {
300 return (0, 0);
301 };
302 t &= POWER235_MOD44[(n % 44) as usize];
303 if t == 0 {
304 return (0, 0);
305 };
306 t &= POWER235_MOD61[(n % 61) as usize];
307 if t == 0 {
308 return (0, 0);
309 };
310 t &= POWER235_MOD63[(n % 63) as usize];
311 if t.odd() {
312 let (y, r) = n.sqrt_rem();
313 if r == 0 {
314 return (y, 2);
315 }
316 }
317 if t & 2 != 0 {
318 let y = n.floor_root(3);
319 if n == y.pow(3) {
320 return (y, 3);
321 }
322 }
323 (0, 0)
324}
325
326const FLINT_ONE_LINE_MULTIPLIER: u32 = 480;
327
328fn factor_one_line_u64(mut n: u64, iters: usize) -> u64 {
330 let orig_n = n;
331 n.wrapping_mul_assign(u64::from(FLINT_ONE_LINE_MULTIPLIER));
332 let mut iin = 0;
333 let mut inn = n;
334 for _ in 0..iters {
335 if iin >= inn {
336 break;
337 }
338 let mut sqrti = inn.floor_sqrt() + 1;
339 let square = sqrti.square();
340 let mmod = square - inn;
341 if mmod.is_square() {
342 sqrti -= mmod.floor_sqrt();
343 let factor = orig_n.gcd(sqrti);
344 if factor != 1 {
345 return factor;
346 }
347 }
348 iin = inn;
349 inn.wrapping_add_assign(n);
350 }
351 0
352}
353
354fn wyhash64(seed: &mut u64) -> u64 {
355 seed.wrapping_add_assign(0x60bee2bee120fc15);
356 let tmp = u128::from(*seed) * 0xa3b195354a39b70d;
357 let tmp = ((tmp >> 64) ^ tmp).wrapping_mul(0x1b03738712fad5c9);
358 u64::wrapping_from((tmp >> 64) ^ tmp)
359}
360
361struct WyhashRandomU64s {
362 seed: u64,
363}
364
365impl WyhashRandomU64s {
366 const fn new() -> Self {
367 Self {
368 seed: 0x452aee49c457bbc3,
369 }
370 }
371}
372
373impl Iterator for WyhashRandomU64s {
374 type Item = u64;
375
376 fn next(&mut self) -> Option<u64> {
377 Some(wyhash64(&mut self.seed))
378 }
379}
380
381const N_FACTOR_PP1_TABLE: [(u16, u8); 34] = [
383 (2784, 5),
384 (1208, 2),
385 (2924, 3),
386 (286, 5),
387 (58, 5),
388 (61, 4),
389 (815, 2),
390 (944, 2),
391 (61, 3),
392 (0, 0),
393 (0, 0),
394 (0, 0),
395 (0, 0),
396 (0, 0),
397 (0, 0),
398 (0, 0),
399 (0, 0),
400 (0, 0),
401 (0, 0),
402 (606, 1),
403 (2403, 1),
404 (2524, 1),
405 (2924, 1),
406 (3735, 2),
407 (669, 2),
408 (6092, 3),
409 (2179, 3),
410 (3922, 3),
411 (6717, 4),
412 (4119, 4),
413 (2288, 4),
414 (9004, 3),
415 (9004, 3),
416 (9004, 3),
417];
418
419fn pp1_pow_ui_u64(mut x: u64, exp: u64, n: u64, ninv: u64, norm: u64) -> (u64, u64) {
422 let x_orig = x;
423 let two = u64::power_of_2(norm + 1);
424 let mut y = mul_mod_helper::<u64, u128>(x, x, n, ninv, norm).mod_sub(two, n);
425 let mut bit = u64::power_of_2(exp.significant_bits() - 2);
426 while bit != 0 {
427 (x, y) = if exp & bit != 0 {
428 (
429 mul_mod_helper::<u64, u128>(x, y, n, ninv, norm).mod_sub(x_orig, n),
430 mul_mod_helper::<u64, u128>(y, y, n, ninv, norm).mod_sub(two, n),
431 )
432 } else {
433 (
434 mul_mod_helper::<u64, u128>(x, x, n, ninv, norm).mod_sub(two, n),
435 mul_mod_helper::<u64, u128>(y, x, n, ninv, norm).mod_sub(x_orig, n),
436 )
437 };
438 bit >>= 1;
439 }
440 (x, y)
441}
442
443fn pp1_factor_u64(mut n: u64, mut x: u64, norm: u64) -> u64 {
445 if norm != 0 {
446 n >>= norm;
447 x >>= norm;
448 }
449 x.mod_sub_assign(2, n);
450 if x == 0 { 0 } else { n.gcd(x) }
451}
452
453fn pp1_find_power_u64(mut x: u64, p: u64, n: u64, ninv: u64, norm: u64) -> (u64, u64, u64) {
457 let mut factor = 1;
458 let mut y = 0;
459 while factor == 1 {
460 (x, y) = pp1_pow_ui_u64(x, p, n, ninv, norm);
461 factor = pp1_factor_u64(n, x, norm);
462 }
463 (factor, x, y)
464}
465
466fn factor_pp1_u64(mut n: u64, b1: u64, c: u64) -> u64 {
469 let mut primes = u64::primes();
470 let sqrt = b1.floor_sqrt();
471 let bits0 = b1.significant_bits();
472 let norm = LeadingZeros::leading_zeros(n);
473 n <<= norm;
474 let n_inverse = u64::precompute_mod_mul_data(&n);
475 let mut x = c << norm;
476 let mut p = 0;
478 let mut old_p = 0;
479 let mut i = 0;
480 let mut old_x = 0;
481 while p < b1 {
482 let j = i + 1024;
483 old_p = p;
484 old_x = x;
485 while i < j {
486 p = primes.next().unwrap();
487 x = if p < sqrt {
488 pp1_pow_ui_u64(
489 x,
490 p.pow(u32::wrapping_from(bits0 / p.significant_bits())),
491 n,
492 n_inverse,
493 norm,
494 )
495 .0
496 } else {
497 pp1_pow_ui_u64(x, p, n, n_inverse, norm).0
498 };
499 i += 1;
500 }
501 let factor = pp1_factor_u64(n, x, norm);
502 if factor == 0 {
503 break;
504 }
505 if factor != 1 {
506 return factor;
507 }
508 }
509 if p < b1 {
510 primes.jump_after(old_p);
512 x = old_x;
513 loop {
514 p = primes.next().unwrap();
515 old_x = x;
516 x = if p < sqrt {
517 pp1_pow_ui_u64(
518 x,
519 p.pow(u32::wrapping_from(bits0 / p.significant_bits())),
520 n,
521 n_inverse,
522 norm,
523 )
524 .0
525 } else {
526 pp1_pow_ui_u64(x, p, n, n_inverse, norm).0
527 };
528 let factor = pp1_factor_u64(n, x, norm);
529 if factor == 0 {
530 break;
531 }
532 if factor != 1 {
533 return factor;
534 }
535 }
536 } else {
537 return 0;
538 }
539 pp1_find_power_u64(old_x, p, n, n_inverse, norm).0
541}
542
543fn factor_pp1_wrapper_u64(n: u64) -> u64 {
545 let bits = n.significant_bits();
546 if bits < 31 {
548 return 0;
549 }
550 let (b1, count) = N_FACTOR_PP1_TABLE[usize::wrapping_from(bits) - 31];
551 let b1 = u64::from(b1);
552 let mut state = WyhashRandomU64s::new();
553 let mask = u64::low_mask((n - 4).significant_bits());
554 let limit = n - 3;
555 for _ in 0..count {
556 let mut randint = u64::MAX;
557 while randint >= limit {
558 randint = state.next().unwrap() & mask;
559 }
560 let factor = factor_pp1_u64(n, b1, randint + 3);
561 if factor != 0 {
562 return factor;
563 }
564 }
565 0
566}
567
568#[doc(hidden)]
572fn limbs_sqrt_rem_to_out_u64(xs_hi: u64, xs_lo: u64) -> (u64, u64, u64, usize) {
573 let high = if xs_hi == 0 { xs_lo } else { xs_hi };
574 assert_ne!(high, 0);
575 let shift = LeadingZeros::leading_zeros(high) >> 1;
576 let two_shift = shift << 1;
577 if xs_hi == 0 {
578 let (sqrt_lo, rem_lo) = if shift == 0 {
579 sqrt_rem_newton::<u64, i64>(high)
580 } else {
581 let sqrt = sqrt_rem_newton::<u64, i64>(high << two_shift).0 >> shift;
582 (sqrt, high - sqrt.square())
583 };
584 (sqrt_lo, 0, rem_lo, usize::from(rem_lo != 0))
585 } else if shift == 0 {
586 let (sqrt_lo, rem_hi, rem_lo) = sqrt_rem_2_newton::<u64, i64>(xs_hi, xs_lo);
587 if rem_hi {
588 (sqrt_lo, 1, rem_lo, 2)
589 } else {
590 (sqrt_lo, 0, rem_lo, usize::from(rem_lo != 0))
591 }
592 } else {
593 let mut lo = xs_lo;
594 let hi = (high << two_shift) | (lo >> (u64::WIDTH - two_shift));
595 let sqrt_lo = sqrt_rem_2_newton::<u64, i64>(hi, lo << two_shift).0 >> shift;
596 lo.wrapping_sub_assign(sqrt_lo.wrapping_square());
597 (sqrt_lo, 0, lo, usize::from(lo != 0))
598 }
599}
600
601const FACTOR_SQUFOF_ITERS: usize = 50_000;
602const FACTOR_ONE_LINE_ITERS: usize = 40_000;
603
604fn ll_factor_squfof_u64(n_hi: u64, n_lo: u64, max_iters: usize) -> u64 {
606 let (mut sqrt_lo, mut rem_lo, num) = if n_hi != 0 {
607 let (sqrt_lo, _, rem_lo, size) = limbs_sqrt_rem_to_out_u64(n_hi, n_lo);
608 (sqrt_lo, rem_lo, size)
609 } else {
610 let (sqrt_lo, rem_lo) = n_lo.sqrt_rem();
611 (sqrt_lo, rem_lo, usize::from(sqrt_lo != 0))
612 };
613 let sqroot = sqrt_lo;
614 let mut p = sqroot;
615 let mut q = rem_lo;
616 if q == 0 || num == 0 {
617 return sqroot;
618 }
619 let l = 1 + ((p << 1).floor_sqrt() << 1);
620 let l2 = l >> 1;
621 let mut qupto = 0;
622 let mut qlast = 1u64;
623 let mut qarr = [0; 50];
624 let mut r = 0;
625 let mut finished_loop = true;
626 for i in 0..max_iters {
627 let iq = (sqroot + p) / q;
628 let pnext = iq * q - p;
629 if q <= l {
630 if q.even() {
631 qarr[qupto] = q >> 1;
632 qupto += 1;
633 if qupto >= 50 {
634 return 0;
635 }
636 } else if q <= l2 {
637 qarr[qupto] = q;
638 qupto += 1;
639 if qupto >= 50 {
640 return 0;
641 }
642 }
643 }
644 let t = qlast.wrapping_add(iq.wrapping_mul(p.wrapping_sub(pnext)));
645 qlast = q;
646 q = t;
647 p = pnext;
648 if i.odd() || !q.is_square() {
649 continue;
650 }
651 r = q.floor_sqrt();
652 if qupto == 0 {
653 finished_loop = false;
654 break;
655 }
656 let mut done = true;
657 for &q in &qarr[..qupto] {
658 if r == q {
659 done = false;
660 break;
661 }
662 }
663 if done {
664 finished_loop = false;
665 break;
666 }
667 if r == 1 {
668 return 0;
669 }
670 }
671 if finished_loop {
672 return 0;
673 }
674 qlast = r;
675 p = p + r * ((sqroot - p) / r);
676 let rem_hi;
677 (rem_hi, rem_lo) = u64::x_mul_y_to_zz(p, p);
678 let sqrt_hi;
679 (sqrt_hi, sqrt_lo) = u64::xx_sub_yy_to_zz(n_hi, n_lo, rem_hi, rem_lo);
680 q = if sqrt_hi != 0 {
681 let norm = LeadingZeros::leading_zeros(qlast);
682 u64::xx_div_mod_y_to_qr(
683 (sqrt_hi << norm) + (sqrt_lo >> (u64::WIDTH - norm)),
684 sqrt_lo << norm,
685 qlast << norm,
686 )
687 .0
688 } else {
689 sqrt_lo / qlast
690 };
691 let mut finished_loop = true;
692 for _ in 0..max_iters {
693 let iq = (sqroot + p) / q;
694 let pnext = iq * q - p;
695 if p == pnext {
696 finished_loop = false;
697 break;
698 }
699 let t = qlast.wrapping_add(iq.wrapping_mul(p.wrapping_sub(pnext)));
700 qlast = q;
701 q = t;
702 p = pnext;
703 }
704 if finished_loop {
705 0
706 } else if q.even() {
707 q >> 1
708 } else {
709 q
710 }
711}
712
713fn factor_squfof_u64(n: u64, iters: usize) -> u64 {
715 let mut factor = ll_factor_squfof_u64(0, n, iters);
716 let mut finished_loop = true;
717 for &p in &SMALL_PRIMES[1..] {
718 if factor != 0 {
719 finished_loop = false;
720 break;
721 }
722 let multiplier = u64::from(p);
723 let (multn_1, multn_0) = u64::x_mul_y_to_zz(multiplier, n);
724 factor = ll_factor_squfof_u64(multn_1, multn_0, iters);
725 if factor != 0 {
726 let (quot, rem) = factor.div_mod(multiplier);
727 if rem == 0 {
728 factor = quot;
729 }
730 if factor == 1 || factor == n {
731 factor = 0;
732 }
733 }
734 }
735 if finished_loop { 0 } else { factor }
736}
737
738const FACTOR_TRIAL_PRIMES: usize = 3000;
739const FACTOR_TRIAL_CUTOFF: u32 = 27449 * 27449;
740
741impl Factor for u8 {
742 type FACTORS = FactorsU8;
743
744 fn factor(&self) -> FactorsU8 {
766 assert_ne!(*self, 0);
767 let mut n = *self;
768 let mut factors = FactorsU8::new();
769 if n == 1 {
770 return factors;
771 }
772 let zeros = n.trailing_zeros();
773 if zeros != 0 {
774 factors.insert(2, zeros as Self);
775 n >>= zeros;
776 if n == 1 {
777 return factors;
778 }
779 }
780 let mut e;
781 let (q, r) = n.div_mod(3);
782 if r == 0 {
783 e = 1;
784 n = q;
785 let (q, r) = n.div_mod(3);
786 if r == 0 {
787 e = 2;
788 n = q;
789 let (q, r) = n.div_mod(3);
790 if r == 0 {
791 e = 3;
792 n = q;
793 let (q, r) = n.div_mod(3);
794 if r == 0 {
795 e = 4;
796 n = q;
797 if n == 3 {
798 e = 5;
799 n = 1;
800 }
801 }
802 }
803 }
804 factors.insert(3, e);
805 if n == 1 {
806 return factors;
807 }
808 }
809 let (q, r) = n.div_mod(5);
810 if r == 0 {
811 e = 1;
812 n = q;
813 let (q, r) = n.div_mod(5);
814 if r == 0 {
815 e = 2;
816 n = q;
817 if n == 5 {
818 e = 3;
819 n = 1;
820 }
821 }
822 factors.insert(5, e);
823 if n == 1 {
824 return factors;
825 }
826 }
827 let (q, r) = n.div_mod(7);
828 if r == 0 {
829 e = 1;
830 n = q;
831 if n == 7 {
832 e = 2;
833 n = 1;
834 }
835 factors.insert(7, e);
836 if n == 1 {
837 return factors;
838 }
839 }
840 match n {
841 121 => {
842 factors.insert(11, 2);
843 }
844 143 => {
845 factors.insert(11, 1);
846 factors.insert(13, 1);
847 }
848 169 => {
849 factors.insert(13, 2);
850 }
851 187 => {
852 factors.insert(11, 1);
853 factors.insert(17, 1);
854 }
855 209 => {
856 factors.insert(11, 1);
857 factors.insert(19, 1);
858 }
859 221 => {
860 factors.insert(13, 1);
861 factors.insert(17, 1);
862 }
863 247 => {
864 factors.insert(13, 1);
865 factors.insert(19, 1);
866 }
867 253 => {
868 factors.insert(11, 1);
869 factors.insert(23, 1);
870 }
871 _ => {
872 factors.insert(n, 1);
873 }
874 }
875 factors
876 }
877}
878
879impl Factor for u16 {
880 type FACTORS = FactorsU16;
881
882 fn factor(&self) -> FactorsU16 {
908 let mut factors = FactorsU16::new();
909 for (f, e) in u32::from(*self).factor() {
910 factors.insert(f as Self, e);
911 }
912 factors
913 }
914}
915
916impl Factor for u32 {
917 type FACTORS = FactorsU32;
918
919 fn factor(&self) -> FactorsU32 {
950 let n = *self;
951 assert_ne!(n, 0);
952 let mut factors = FactorsU32::new();
953 let cofactor = factor_trial_range_u32(&mut factors, n, FACTOR_TRIAL_PRIMES);
954 if cofactor == 1 {
955 return factors;
956 }
957 if cofactor.is_prime() {
958 factors.insert(cofactor, 1);
959 return factors;
960 }
961 let mut factor_arr = [0; MAX_FACTORS_IN_U32];
962 let mut exp_arr = [0; MAX_FACTORS_IN_U32];
963 factor_arr[0] = cofactor;
964 let mut factors_left = 1;
965 exp_arr[0] = 1;
966 let cutoff = FACTOR_TRIAL_CUTOFF;
967 while factors_left != 0 {
968 let mut factor = factor_arr[factors_left - 1];
969 if factor >= cutoff {
970 let (mut cofactor, exp) = factor_square_u32(factor);
971 if cofactor != 0 {
972 exp_arr[factors_left - 1] *= exp;
973 factor = cofactor;
974 factor_arr[factors_left - 1] = factor;
975 }
976 if factor >= cutoff && !factor.is_prime() {
977 cofactor = Self::exact_from(factor_one_line_u64(
978 u64::from(factor),
979 FACTOR_ONE_LINE_ITERS,
980 ));
981 exp_arr[factors_left] = exp_arr[factors_left - 1];
982 factor_arr[factors_left] = cofactor;
983 factor_arr[factors_left - 1] /= cofactor;
984 factors_left += 1;
985 } else {
986 factors.insert(factor, exp_arr[factors_left - 1]);
987 factors_left -= 1;
988 }
989 } else {
990 factors.insert(factor, exp_arr[factors_left - 1]);
991 factors_left -= 1;
992 }
993 }
994 factors
995 }
996}
997
998const FACTOR_ONE_LINE_MAX: u64 = 1 << 39;
999
1000impl Factor for u64 {
1001 type FACTORS = FactorsU64;
1002
1003 fn factor(&self) -> FactorsU64 {
1034 let n = *self;
1035 assert_ne!(n, 0);
1036 let mut factors = FactorsU64::new();
1037 let cofactor = factor_trial_range_u64(&mut factors, n, FACTOR_TRIAL_PRIMES);
1038 if cofactor == 1 {
1039 return factors;
1040 }
1041 if cofactor.is_prime() {
1042 factors.insert(cofactor, 1);
1043 return factors;
1044 }
1045 let mut factor_arr = [0; MAX_FACTORS_IN_U64];
1046 let mut exp_arr = [0; MAX_FACTORS_IN_U64];
1047 factor_arr[0] = cofactor;
1048 let mut factors_left = 1;
1049 exp_arr[0] = 1;
1050 const CUTOFF: u64 = FACTOR_TRIAL_CUTOFF as u64;
1051 while factors_left != 0 {
1052 let mut factor = factor_arr[factors_left - 1];
1053 if factor >= CUTOFF {
1054 let (mut cofactor, exp) = factor_power23_u64(factor);
1055 if cofactor != 0 {
1056 exp_arr[factors_left - 1] *= exp;
1057 factor = cofactor;
1058 factor_arr[factors_left - 1] = factor;
1059 }
1060 if factor >= CUTOFF && !factor.is_prime() {
1061 cofactor = 0;
1062 if factor < FACTOR_ONE_LINE_MAX {
1063 cofactor = factor_one_line_u64(factor, FACTOR_ONE_LINE_ITERS);
1064 }
1065 if cofactor == 0 {
1066 cofactor = factor_pp1_wrapper_u64(factor);
1067 if cofactor == 0 {
1068 cofactor = factor_squfof_u64(factor, FACTOR_SQUFOF_ITERS);
1069 assert_ne!(cofactor, 0);
1070 }
1071 }
1072 exp_arr[factors_left] = exp_arr[factors_left - 1];
1073 factor_arr[factors_left] = cofactor;
1074 factor_arr[factors_left - 1] /= cofactor;
1075 factors_left += 1;
1076 } else {
1077 factors.insert(factor, exp_arr[factors_left - 1]);
1078 factors_left -= 1;
1079 }
1080 } else {
1081 factors.insert(factor, exp_arr[factors_left - 1]);
1082 factors_left -= 1;
1083 }
1084 }
1085 factors
1086 }
1087}
1088
1089impl Factor for usize {
1090 type FACTORS = FactorsUsize;
1091
1092 fn factor(&self) -> FactorsUsize {
1121 let mut factors = FactorsUsize::new();
1122 if USIZE_IS_U32 {
1123 for (f, e) in (*self as u32).factor() {
1124 factors.insert(f as Self, e);
1125 }
1126 } else {
1127 for (f, e) in (*self as u64).factor() {
1128 factors.insert(f as Self, e);
1129 }
1130 }
1131 factors
1132 }
1133}