factorial_from_trinomial_coefficients.pl 746 B

1234567891011121314151617181920212223242526272829303132333435363738
  1. #!/usr/bin/perl
  2. # An efficient algorithm for computing n! using trinomial coefficients.
  3. # See also:
  4. # https://oeis.org/A056040
  5. # https://oeis.org/A000142/a000142.pdf
  6. use 5.020;
  7. use strict;
  8. use warnings;
  9. use Math::GMPz;
  10. use experimental qw(signatures);
  11. sub trinomial ($m, $n, $o) {
  12. my $prod = Math::GMPz::Rmpz_init();
  13. Math::GMPz::Rmpz_bin_uiui($prod, $m + $n + $o, $o);
  14. if ($n) {
  15. my $t = Math::GMPz::Rmpz_init();
  16. Math::GMPz::Rmpz_bin_uiui($t, $m + $n, $n);
  17. Math::GMPz::Rmpz_mul($prod, $prod, $t);
  18. }
  19. return $prod;
  20. }
  21. sub Factorial($n) {
  22. return 1 if ($n < 2);
  23. Factorial($n >> 1)**2 * trinomial($n >> 1, $n % 2, $n >> 1);
  24. }
  25. foreach my $n (0 .. 30) {
  26. say "$n! = ", Factorial($n);
  27. }