malachite_nz/natural/arithmetic/factorial.rs
1// Copyright © 2026 Mikhail Hogrefe
2//
3// Uses code adopted from the GNU MP Library.
4//
5// `limb_apprsqrt`, `mpz_2multiswing_1`, `mpz_oddfac_1`, `mpz_fac_ui`, and `mpz_2fac_ui`
6// contributed to the GNU project by Marco Bodrato.
7//
8// Copyright © 1991-2018 Free Software Foundation, Inc.
9//
10// This file is part of Malachite.
11//
12// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
13// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
14// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
15
16use crate::natural::arithmetic::mul::product_of_limbs::limbs_product;
17use crate::natural::arithmetic::mul::{
18 limbs_mul_greater_to_out, limbs_mul_greater_to_out_scratch_len,
19};
20use crate::natural::arithmetic::square::{limbs_square_to_out, limbs_square_to_out_scratch_len};
21use crate::natural::{Natural, bit_to_limb_count_floor};
22use crate::platform::{
23 Limb, NTH_ROOT_NUMB_MASK_TABLE, ODD_DOUBLEFACTORIAL_TABLE_LIMIT, ODD_DOUBLEFACTORIAL_TABLE_MAX,
24 ODD_FACTORIAL_TABLE_LIMIT, ONE_LIMB_ODD_DOUBLEFACTORIAL_TABLE, ONE_LIMB_ODD_FACTORIAL_TABLE,
25 TABLE_2N_MINUS_POPC_2N, TABLE_LIMIT_2N_MINUS_POPC_2N,
26};
27use alloc::vec::Vec;
28use malachite_base::fail_on_untested_path;
29use malachite_base::num::arithmetic::traits::{
30 DoubleFactorial, Factorial, Gcd, Multifactorial, Parity, Pow, PowerOf2, Square, Subfactorial,
31 XMulYToZZ,
32};
33use malachite_base::num::basic::integers::PrimitiveInt;
34use malachite_base::num::basic::traits::One;
35use malachite_base::num::conversion::traits::{ConvertibleFrom, ExactFrom, WrappingFrom};
36#[cfg(feature = "32_bit_limbs")]
37use malachite_base::num::factorization::prime_sieve::limbs_prime_sieve_u32;
38#[cfg(not(feature = "32_bit_limbs"))]
39use malachite_base::num::factorization::prime_sieve::limbs_prime_sieve_u64;
40use malachite_base::num::factorization::prime_sieve::{id_to_n, limbs_prime_sieve_size, n_to_bit};
41use malachite_base::num::logic::traits::{BitAccess, CountOnes, NotAssign, SignificantBits};
42
43pub_test! {subfactorial_naive(n: u64) -> Natural {
44 let mut f = Natural::ONE;
45 let mut b = true;
46 for i in 1..=n {
47 f *= Natural::from(i);
48 if b {
49 f -= Natural::ONE;
50 } else {
51 f += Natural::ONE;
52 }
53 b.not_assign();
54 }
55 f
56}}
57
58// Returns an approximation of the square root of x.
59//
60// It gives:
61// ```
62// limb_apprsqrt(x) ^ 2 <= x < (limb_apprsqrt(x) + 1) ^ 2
63// ```
64// or
65// ```
66// x <= limb_apprsqrt(x) ^ 2 <= x * 9 / 8
67// ```
68//
69// This is equivalent to `limb_apprsqrt` in `mpz/oddfac_1.c`, GMP 6.2.1.
70fn limbs_approx_sqrt(x: u64) -> u64 {
71 assert!(x > 2);
72 let s = x.significant_bits() >> 1;
73 (u64::power_of_2(s) + (x >> s)) >> 1
74}
75
76pub(crate) const fn bit_to_n(bit: u64) -> u64 {
77 (bit * 3 + 4) | 1
78}
79
80// `limbs_2_multiswing_odd` computes the odd part of the 2-multiswing factorial of the parameter n.
81// The result x is an odd positive integer so that multiswing(n, 2) = x * 2 ^ a.
82//
83// The algorithm is described by Peter Luschny in "Divide, Swing and Conquer the Factorial!".
84//
85// The pointer sieve points to `limbs_prime_sieve_size(n)` limbs containing a bit array where primes
86// are marked as 0. Enough limbs must be pointed by `factors`.
87//
88// # Worst-case complexity
89// $T(n) = O(n (\log n)^2 \log\log n)$
90//
91// $M(n) = O(n \log n)$
92//
93// where $T$ is time, $M$ is additional memory, and $n$ is `n`.
94//
95// This is equivalent to `mpz_2multiswing_1` from `mpz/oddfac_1.c`, GMP 6.2.1, where `x_and_sieve`
96// is provided as a single slice, allowing the sieve to be overwritten.
97#[allow(clippy::useless_conversion)]
98fn limbs_2_multiswing_odd(
99 x_and_sieve: &mut [Limb],
100 x_len: usize,
101 mut n: Limb,
102 factors: &mut [Limb],
103) -> usize {
104 assert!(n > 25);
105 let mut prod = if n.odd() { n } else { 1 };
106 n.clear_bit(0);
107 let max_prod = Limb::MAX / (n - 1);
108 // Handle prime = 3 separately
109 let mut j = 0;
110 if prod > max_prod {
111 factors[j] = prod;
112 j += 1;
113 prod = 1;
114 }
115 let mut q = n;
116 while q >= 3 {
117 q /= 3;
118 if q.odd() {
119 prod *= 3;
120 }
121 }
122 let limb_n = n;
123 let n = u64::exact_from(n);
124 // Swing primes from 5 to n / 3
125 let mut s = limbs_approx_sqrt(n);
126 assert!(s >= 5);
127 s = n_to_bit(s);
128 assert!(bit_to_n(s + 1).square() > n);
129 assert!(s < n_to_bit(n / 3));
130 let start = const { n_to_bit(5) };
131 let mut index = bit_to_limb_count_floor(start);
132 let mut mask = Limb::power_of_2(start & Limb::WIDTH_MASK);
133 let sieve = &mut x_and_sieve[x_len..];
134 for i in start + 1..=s + 1 {
135 if sieve[index] & mask == 0 {
136 let prime = Limb::exact_from(id_to_n(i));
137 if prod > max_prod {
138 factors[j] = prod;
139 j += 1;
140 prod = 1;
141 }
142 let mut q = limb_n;
143 while q >= prime {
144 q /= prime;
145 if q.odd() {
146 prod *= prime;
147 }
148 }
149 }
150 mask <<= 1;
151 if mask == 0 {
152 mask = 1;
153 index += 1;
154 }
155 }
156 assert!(max_prod <= const { Limb::MAX / 3 });
157 let l_max_prod = max_prod * 3;
158 for i in s + 2..=n_to_bit(n / 3) + 1 {
159 if sieve[index] & mask == 0 {
160 let prime = Limb::exact_from(id_to_n(i));
161 if (limb_n / prime).odd() {
162 if prod > l_max_prod {
163 factors[j] = prod;
164 j += 1;
165 prod = prime;
166 } else {
167 prod *= prime;
168 }
169 }
170 }
171 mask <<= 1;
172 if mask == 0 {
173 mask = 1;
174 index += 1;
175 }
176 }
177 // Store primes from (n + 1) / 2 to n
178 let start = n_to_bit(n >> 1) + 1;
179 let mut index = bit_to_limb_count_floor(start);
180 let mut mask = Limb::power_of_2(start & Limb::WIDTH_MASK);
181 for i in start + 1..=n_to_bit(n) + 1 {
182 if sieve[index] & mask == 0 {
183 let prime = Limb::exact_from(id_to_n(i));
184 if prod > max_prod {
185 factors[j] = prod;
186 j += 1;
187 prod = prime;
188 } else {
189 prod *= prime;
190 }
191 }
192 mask <<= 1;
193 if mask == 0 {
194 mask = 1;
195 index += 1;
196 }
197 }
198 if j != 0 {
199 factors[j] = prod;
200 j += 1;
201 match limbs_product(&mut x_and_sieve[..x_len], &mut factors[..j]) {
202 (size, None) => size,
203 (size, Some(new_x_and_sieve)) => {
204 x_and_sieve[..size].copy_from_slice(&new_x_and_sieve[..size]);
205 size
206 }
207 }
208 } else {
209 // not triggered by the first billion inputs
210 fail_on_untested_path("limbs_2_multiswing_odd, j == 0");
211 x_and_sieve[0] = prod;
212 1
213 }
214}
215
216pub(crate) const FAC_DSC_THRESHOLD: usize = 236;
217
218const fn clb2(x: usize) -> usize {
219 let floor_log_base_2 = (usize::WIDTH as usize - x.leading_zeros() as usize) - 1;
220 if x.is_power_of_two() {
221 floor_log_base_2
222 } else {
223 floor_log_base_2 + 1
224 }
225}
226
227const FACTORS_PER_LIMB: usize =
228 (Limb::WIDTH << 1) as usize / (clb2(FAC_DSC_THRESHOLD * FAC_DSC_THRESHOLD - 1) + 1) - 1;
229
230// n ^ log <= Limb::MAX: a limb can store log factors less than n.
231//
232// This is equivalent to log_n_max, `gmp-impl.h`, GMP 6.2.1.
233pub(crate) fn log_n_max(n: Limb) -> u64 {
234 // NTH_ROOT_NUMB_MASK_TABLE[0] is Limb::MAX, so a match will always be found
235 u64::wrapping_from(
236 NTH_ROOT_NUMB_MASK_TABLE
237 .iter()
238 .rposition(|&x| n <= x)
239 .unwrap(),
240 ) + 1
241}
242
243// `limbs_odd_factorial` computes the odd part of the factorial of the parameter n, i.e. n! = x * 2
244// ^ a, where x is the returned value: an odd positive integer.
245//
246// If `double` is `true`, a square is skipped in the DSC part, e.g. if n is odd, n >
247// FAC_DSC_THRESHOLD and `double` is true, x is set to n!!.
248//
249// If n is too small, `double` is ignored, and an assert can be triggered.
250//
251// TODO: FAC_DSC_THRESHOLD is used here with two different roles:
252// - to decide when prime factorisation is needed,
253// - to stop the recursion, once sieving is done.
254// Maybe two thresholds can do a better job.
255//
256// # Worst-case complexity
257// $T(n) = O(n (\log n)^2 \log\log n)$
258//
259// $M(n) = O(n \log n)$
260//
261// where $T$ is time, $M$ is additional memory, and $n$ is `n`.
262//
263// This is equivalent to `mpz_oddfac_1` from `mpz/oddfac_1.c`, GMP 6.2.1.
264
265pub_crate_test! {
266#[allow(clippy::redundant_comparisons)]
267limbs_odd_factorial(n: usize, double: bool) -> Vec<Limb> {
268 assert!(Limb::convertible_from(n));
269 if double {
270 assert!(n > ODD_DOUBLEFACTORIAL_TABLE_LIMIT + 1 && n >= FAC_DSC_THRESHOLD);
271 }
272 if n <= ODD_FACTORIAL_TABLE_LIMIT {
273 vec![ONE_LIMB_ODD_FACTORIAL_TABLE[n]]
274 } else if n <= ODD_DOUBLEFACTORIAL_TABLE_LIMIT + 1 {
275 let (hi, lo) = Limb::x_mul_y_to_zz(
276 ONE_LIMB_ODD_DOUBLEFACTORIAL_TABLE[(n - 1) >> 1],
277 ONE_LIMB_ODD_FACTORIAL_TABLE[n >> 1],
278 );
279 vec![lo, hi]
280 } else {
281 // Compute the number of recursive steps for the DSC algorithm
282 let mut m = n;
283 let mut s = 0;
284 while m >= FAC_DSC_THRESHOLD {
285 m >>= 1;
286 s += 1;
287 }
288 let mut factors = vec![0; m / FACTORS_PER_LIMB + 1];
289 assert!(m >= FACTORS_PER_LIMB);
290 const LIMIT_P1: usize = ODD_DOUBLEFACTORIAL_TABLE_LIMIT + 1;
291 assert!(m > LIMIT_P1);
292 let mut j = 0;
293 let mut prod = 1;
294 let mut max_prod = const { Limb::MAX / (FAC_DSC_THRESHOLD * FAC_DSC_THRESHOLD) as Limb };
295 assert!(m > LIMIT_P1);
296 loop {
297 factors[j] = ODD_DOUBLEFACTORIAL_TABLE_MAX;
298 j += 1;
299 let mut diff = (m - ODD_DOUBLEFACTORIAL_TABLE_LIMIT) & const { 2usize.wrapping_neg() };
300 if diff & 2 != 0 {
301 let f = (ODD_DOUBLEFACTORIAL_TABLE_LIMIT + diff) as Limb;
302 if prod > max_prod {
303 factors[j] = prod;
304 j += 1;
305 prod = f;
306 } else {
307 prod *= f;
308 }
309 diff -= 2;
310 }
311 if diff != 0 {
312 let mut fac = (ODD_DOUBLEFACTORIAL_TABLE_LIMIT + 2)
313 * (ODD_DOUBLEFACTORIAL_TABLE_LIMIT + diff);
314 loop {
315 let f = fac as Limb;
316 if prod > max_prod {
317 factors[j] = prod;
318 j += 1;
319 prod = f;
320 } else {
321 prod *= f;
322 }
323 diff -= 4;
324 fac += diff << 1;
325 if diff == 0 {
326 break;
327 }
328 }
329 }
330 max_prod <<= 2;
331 m >>= 1;
332 if m <= LIMIT_P1 {
333 break;
334 }
335 }
336 factors[j] = prod;
337 j += 1;
338 factors[j] = ONE_LIMB_ODD_DOUBLEFACTORIAL_TABLE[(m - 1) >> 1];
339 j += 1;
340 factors[j] = ONE_LIMB_ODD_FACTORIAL_TABLE[m >> 1];
341 j += 1;
342 let mut out = Vec::new();
343 let (out_size, new_out) = limbs_product(&mut out, &mut factors[..j]);
344 out = new_out.unwrap();
345 out.truncate(out_size);
346 if s != 0 {
347 // Use the algorithm described by Peter Luschny in "Divide, Swing and Conquer the
348 // Factorial!".
349 let mut size = (n >> Limb::LOG_WIDTH) + 4;
350 let n_m_1 = u64::exact_from(n - 1);
351 assert!(limbs_prime_sieve_size::<Limb>(n_m_1) < size - (size >> 1));
352 // 2-multiswing(n) < 2^(n - 1) * sqrt(n / pi) < 2 ^ (n + Limb::WIDTH); One more can be
353 // overwritten by mul, another for the sieve.
354 let mut swing_and_sieve = vec![0; size];
355 // Put the sieve on the second half; it will be overwritten by the last
356 // `limbs_2_multiswing_odd`.
357 let sieve_offset = (size >> 1) + 1;
358 let ss_len = swing_and_sieve.len() - 1;
359 #[cfg(feature = "32_bit_limbs")]
360 let count = limbs_prime_sieve_u32(&mut swing_and_sieve[sieve_offset..ss_len], n_m_1);
361 #[cfg(not(feature = "32_bit_limbs"))]
362 let count = limbs_prime_sieve_u64(&mut swing_and_sieve[sieve_offset..ss_len], n_m_1);
363 size = usize::exact_from((count + 1) / log_n_max(Limb::exact_from(n)) + 1);
364 let mut factors = vec![0; size];
365 let mut out_len = out.len();
366 for i in (0..s).rev() {
367 let ns = limbs_2_multiswing_odd(
368 &mut swing_and_sieve,
369 sieve_offset,
370 Limb::exact_from(n >> i),
371 &mut factors,
372 );
373 let mut square;
374 if double && i == 0 {
375 size = out_len;
376 square = vec![0; size];
377 square[..out_len].copy_from_slice(&out[..out_len]);
378 } else {
379 size = out_len << 1;
380 square = vec![0; size];
381 let mut square_scratch = vec![0; limbs_square_to_out_scratch_len(out_len)];
382 limbs_square_to_out(&mut square, &out[..out_len], &mut square_scratch);
383 if square[size - 1] == 0 {
384 size -= 1;
385 }
386 }
387 out_len = size + ns;
388 out.resize(out_len, 0);
389 assert!(ns <= size);
390 // n != n$ * floor(n / 2)! ^ 2
391 let mut mul_scratch = vec![0; limbs_mul_greater_to_out_scratch_len(size, ns)];
392 if limbs_mul_greater_to_out(
393 &mut out,
394 &square[..size],
395 &swing_and_sieve[..ns],
396 &mut mul_scratch,
397 ) == 0
398 {
399 out_len -= 1;
400 }
401 }
402 }
403 if *out.last().unwrap() == 0 {
404 out.pop();
405 }
406 out
407 }
408}}
409
410const FAC_ODD_THRESHOLD: Limb = 24;
411
412#[cfg(feature = "32_bit_limbs")]
413const SMALL_FACTORIAL_LIMIT: u64 = 13;
414#[cfg(not(feature = "32_bit_limbs"))]
415const SMALL_FACTORIAL_LIMIT: u64 = 21;
416
417impl Factorial for Natural {
418 /// Computes the factorial of a number.
419 ///
420 /// $$
421 /// f(n) = n! = 1 \times 2 \times 3 \times \cdots \times n.
422 /// $$
423 ///
424 /// $n! = O(\sqrt{n}(n/e)^n)$.
425 ///
426 /// # Worst-case complexity
427 /// $T(n) = O(n (\log n)^2 \log\log n)$
428 ///
429 /// $M(n) = O(n \log n)$
430 ///
431 /// where $T$ is time, $M$ is additional memory, and $n$ is `n`.
432 ///
433 /// # Examples
434 /// ```
435 /// use malachite_base::num::arithmetic::traits::Factorial;
436 /// use malachite_nz::natural::Natural;
437 ///
438 /// assert_eq!(Natural::factorial(0), 1);
439 /// assert_eq!(Natural::factorial(1), 1);
440 /// assert_eq!(Natural::factorial(2), 2);
441 /// assert_eq!(Natural::factorial(3), 6);
442 /// assert_eq!(Natural::factorial(4), 24);
443 /// assert_eq!(Natural::factorial(5), 120);
444 /// assert_eq!(
445 /// Natural::factorial(100).to_string(),
446 /// "9332621544394415268169923885626670049071596826438162146859296389521759999322991560894\
447 /// 1463976156518286253697920827223758251185210916864000000000000000000000000"
448 /// );
449 /// ```
450 ///
451 /// This is equivalent to `mpz_fac_ui` from `mpz/fac_ui.c`, GMP 6.2.1.
452 #[allow(clippy::useless_conversion)]
453 fn factorial(n: u64) -> Self {
454 assert!(Limb::convertible_from(n));
455 if n < SMALL_FACTORIAL_LIMIT {
456 Self::from(Limb::factorial(n))
457 } else if n < u64::from(FAC_ODD_THRESHOLD) {
458 let mut factors =
459 vec![0; usize::wrapping_from(n - SMALL_FACTORIAL_LIMIT) / FACTORS_PER_LIMB + 2];
460 factors[0] = Limb::factorial(SMALL_FACTORIAL_LIMIT - 1);
461 let mut j = 1;
462 let n = Limb::wrapping_from(n);
463 let mut prod = n;
464 const MAX_PROD: Limb = Limb::MAX / (FAC_ODD_THRESHOLD | 1);
465 const LIMB_SMALL_FACTORIAL_LIMIT: Limb = SMALL_FACTORIAL_LIMIT as Limb;
466 for i in (LIMB_SMALL_FACTORIAL_LIMIT..n).rev() {
467 if prod > MAX_PROD {
468 factors[j] = prod;
469 j += 1;
470 prod = i;
471 } else {
472 prod *= i;
473 }
474 }
475 factors[j] = prod;
476 j += 1;
477 let mut xs = Vec::new();
478 let new_xs = limbs_product(&mut xs, &mut factors[..j]).1;
479 xs = new_xs.unwrap();
480 Self::from_owned_limbs_asc(xs)
481 } else {
482 let count = if n <= TABLE_LIMIT_2N_MINUS_POPC_2N {
483 u64::from(TABLE_2N_MINUS_POPC_2N[usize::exact_from((n >> 1) - 1)])
484 } else {
485 n - CountOnes::count_ones(n)
486 };
487 Self::from_owned_limbs_asc(limbs_odd_factorial(usize::exact_from(n), false)) << count
488 }
489 }
490}
491
492const FAC_2DSC_THRESHOLD: Limb = ((FAC_DSC_THRESHOLD << 1) | (FAC_DSC_THRESHOLD & 1)) as Limb;
493
494impl DoubleFactorial for Natural {
495 /// Computes the double factorial of a number.
496 ///
497 /// $$
498 /// f(n) = n!! = n \times (n - 2) \times (n - 4) \times \cdots \times i,
499 /// $$
500 /// where $i$ is 1 if $n$ is odd and $2$ if $n$ is even.
501 ///
502 /// $n!! = O(\sqrt{n}(n/e)^{n/2})$.
503 ///
504 /// # Worst-case complexity
505 /// $T(n) = O(n (\log n)^2 \log\log n)$
506 ///
507 /// $M(n) = O(n \log n)$
508 ///
509 /// # Examples
510 /// ```
511 /// use malachite_base::num::arithmetic::traits::DoubleFactorial;
512 /// use malachite_nz::natural::Natural;
513 ///
514 /// assert_eq!(Natural::double_factorial(0), 1);
515 /// assert_eq!(Natural::double_factorial(1), 1);
516 /// assert_eq!(Natural::double_factorial(2), 2);
517 /// assert_eq!(Natural::double_factorial(3), 3);
518 /// assert_eq!(Natural::double_factorial(4), 8);
519 /// assert_eq!(Natural::double_factorial(5), 15);
520 /// assert_eq!(Natural::double_factorial(6), 48);
521 /// assert_eq!(Natural::double_factorial(7), 105);
522 /// assert_eq!(
523 /// Natural::double_factorial(99).to_string(),
524 /// "2725392139750729502980713245400918633290796330545803413734328823443106201171875"
525 /// );
526 /// assert_eq!(
527 /// Natural::double_factorial(100).to_string(),
528 /// "34243224702511976248246432895208185975118675053719198827915654463488000000000000"
529 /// );
530 /// ```
531 ///
532 /// This is equivalent to `mpz_2fac_ui` from `mpz/2fac_ui.c`, GMP 6.2.1.
533 fn double_factorial(n: u64) -> Self {
534 assert!(Limb::convertible_from(n));
535 if n.even() {
536 // n is even, n = 2k, (2k)!! = k! 2^k
537 let half_n = usize::wrapping_from(n >> 1);
538 let count = if n <= TABLE_LIMIT_2N_MINUS_POPC_2N && n != 0 {
539 u64::from(TABLE_2N_MINUS_POPC_2N[half_n - 1])
540 } else {
541 n - CountOnes::count_ones(n)
542 };
543 Self::from_owned_limbs_asc(limbs_odd_factorial(half_n, false)) << count
544 } else if n <= u64::wrapping_from(ODD_DOUBLEFACTORIAL_TABLE_LIMIT) {
545 Self::from(ONE_LIMB_ODD_DOUBLEFACTORIAL_TABLE[usize::wrapping_from(n >> 1)])
546 } else if n < u64::wrapping_from(FAC_2DSC_THRESHOLD) {
547 let mut factors = vec![0; usize::exact_from(n) / (FACTORS_PER_LIMB << 1) + 1];
548 factors[0] = ODD_DOUBLEFACTORIAL_TABLE_MAX;
549 let mut j = 1;
550 let mut n = Limb::wrapping_from(n);
551 let mut prod = n;
552 let max_prod = Limb::MAX / FAC_2DSC_THRESHOLD;
553 const LIMIT: Limb = ODD_DOUBLEFACTORIAL_TABLE_LIMIT as Limb + 2;
554 while n > LIMIT {
555 n -= 2;
556 if prod > max_prod {
557 factors[j] = prod;
558 j += 1;
559 prod = n;
560 } else {
561 prod *= n;
562 }
563 }
564 factors[j] = prod;
565 j += 1;
566 let mut xs = Vec::new();
567 let new_xs = limbs_product(&mut xs, &mut factors[..j]).1;
568 xs = new_xs.unwrap();
569 Self::from_owned_limbs_asc(xs)
570 } else {
571 Self::from_owned_limbs_asc(limbs_odd_factorial(usize::exact_from(n), true))
572 }
573 }
574}
575
576impl Multifactorial for Natural {
577 /// Computes a multifactorial of a number.
578 ///
579 /// $$
580 /// f(n, m) = n!^{(m)} = n \times (n - m) \times (n - 2m) \times \cdots \times i.
581 /// $$
582 /// If $n$ is divisible by $m$, then $i$ is $m$; otherwise, $i$ is the remainder when $n$ is
583 /// divided by $m$.
584 ///
585 /// $n!^{(m)} = O(\sqrt{n}(n/e)^{n/m})$.
586 ///
587 /// # Worst-case complexity
588 /// $T(n, m) = O(n (\log n)^2 \log\log n)$
589 ///
590 /// $M(n, m) = O(n \log n)$
591 ///
592 /// # Examples
593 /// ```
594 /// use malachite_base::num::arithmetic::traits::Multifactorial;
595 /// use malachite_nz::natural::Natural;
596 ///
597 /// assert_eq!(Natural::multifactorial(0, 1), 1);
598 /// assert_eq!(Natural::multifactorial(1, 1), 1);
599 /// assert_eq!(Natural::multifactorial(2, 1), 2);
600 /// assert_eq!(Natural::multifactorial(3, 1), 6);
601 /// assert_eq!(Natural::multifactorial(4, 1), 24);
602 /// assert_eq!(Natural::multifactorial(5, 1), 120);
603 ///
604 /// assert_eq!(Natural::multifactorial(0, 2), 1);
605 /// assert_eq!(Natural::multifactorial(1, 2), 1);
606 /// assert_eq!(Natural::multifactorial(2, 2), 2);
607 /// assert_eq!(Natural::multifactorial(3, 2), 3);
608 /// assert_eq!(Natural::multifactorial(4, 2), 8);
609 /// assert_eq!(Natural::multifactorial(5, 2), 15);
610 /// assert_eq!(Natural::multifactorial(6, 2), 48);
611 /// assert_eq!(Natural::multifactorial(7, 2), 105);
612 ///
613 /// assert_eq!(Natural::multifactorial(0, 3), 1);
614 /// assert_eq!(Natural::multifactorial(1, 3), 1);
615 /// assert_eq!(Natural::multifactorial(2, 3), 2);
616 /// assert_eq!(Natural::multifactorial(3, 3), 3);
617 /// assert_eq!(Natural::multifactorial(4, 3), 4);
618 /// assert_eq!(Natural::multifactorial(5, 3), 10);
619 /// assert_eq!(Natural::multifactorial(6, 3), 18);
620 /// assert_eq!(Natural::multifactorial(7, 3), 28);
621 /// assert_eq!(Natural::multifactorial(8, 3), 80);
622 /// assert_eq!(Natural::multifactorial(9, 3), 162);
623 ///
624 /// assert_eq!(
625 /// Natural::multifactorial(100, 3).to_string(),
626 /// "174548867015437739741494347897360069928419328000000000"
627 /// );
628 /// ```
629 fn multifactorial(mut n: u64, mut m: u64) -> Self {
630 assert_ne!(m, 0);
631 assert!(Limb::convertible_from(n));
632 assert!(Limb::convertible_from(m));
633 if n < 3 || n - 3 < m - 1 {
634 // n < 3 || n - 1 <= m
635 if n == 0 { Self::ONE } else { Self::from(n) }
636 } else {
637 // 0 < m < n - 1 < Limb::MAX
638 let gcd = n.gcd(m);
639 if gcd > 1 {
640 n /= gcd;
641 m /= gcd;
642 }
643 if m <= 2 {
644 // fac or 2fac
645 if m == 1 {
646 match gcd {
647 gcd if gcd > 2 => Self::from(gcd).pow(n) * Self::factorial(n),
648 2 => Self::double_factorial(n << 1),
649 _ => Self::factorial(n),
650 }
651 } else if gcd > 1 {
652 // m == 2
653 Self::from(gcd).pow((n >> 1) + 1) * Self::double_factorial(n)
654 } else {
655 Self::double_factorial(n)
656 }
657 } else {
658 // m >= 3, gcd(n,m) = 1
659 let reduced_n = n / m + 1;
660 let mut n = Limb::exact_from(n);
661 let m = Limb::exact_from(m);
662 let mut j = 0;
663 let mut prod = n;
664 n -= m;
665 let max_prod = Limb::MAX / n;
666 let mut factors = vec![0; usize::exact_from(reduced_n / log_n_max(n) + 2)];
667 while n > m {
668 if prod > max_prod {
669 factors[j] = prod;
670 j += 1;
671 prod = n;
672 } else {
673 prod *= n;
674 }
675 n -= m;
676 }
677 factors[j] = n;
678 j += 1;
679 factors[j] = prod;
680 j += 1;
681 let mut xs = Vec::new();
682 let new_xs = limbs_product(&mut xs, &mut factors[..j]).1;
683 xs = new_xs.unwrap();
684 let x = Self::from_owned_limbs_asc(xs);
685 if gcd == 1 {
686 x
687 } else {
688 Self::from(gcd).pow(reduced_n) * x
689 }
690 }
691 }
692 }
693}
694
695impl Subfactorial for Natural {
696 /// Computes the subfactorial of a number.
697 ///
698 /// The subfactorial of $n$ counts the number of derangements of a set of size $n$; a
699 /// derangement is a permutation with no fixed points.
700 ///
701 /// $$
702 /// f(n) = \\ !n = \lfloor n!/e \rfloor.
703 /// $$
704 ///
705 /// $!n = O(n!) = O(\sqrt{n}(n/e)^n)$.
706 ///
707 /// # Worst-case complexity
708 /// $T(n) = O(n^2)$
709 ///
710 /// $M(n) = O(n)$
711 ///
712 /// # Examples
713 /// ```
714 /// use malachite_base::num::arithmetic::traits::Subfactorial;
715 /// use malachite_nz::natural::Natural;
716 ///
717 /// assert_eq!(Natural::subfactorial(0), 1);
718 /// assert_eq!(Natural::subfactorial(1), 0);
719 /// assert_eq!(Natural::subfactorial(2), 1);
720 /// assert_eq!(Natural::subfactorial(3), 2);
721 /// assert_eq!(Natural::subfactorial(4), 9);
722 /// assert_eq!(Natural::subfactorial(5), 44);
723 /// assert_eq!(
724 /// Natural::subfactorial(100).to_string(),
725 /// "3433279598416380476519597752677614203236578380537578498354340028268518079332763243279\
726 /// 1396429850988990237345920155783984828001486412574060553756854137069878601"
727 /// );
728 /// ```
729 #[inline]
730 fn subfactorial(n: u64) -> Self {
731 subfactorial_naive(n)
732 }
733}