The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
#!/usr/bin/env perl
use strict;
use warnings;

use Test::More;
use Math::Prime::Util::GMP qw/primorial pn_primorial factorial/;

my @small_primes = qw/
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71
73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173
179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277 281
283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397 401 409
419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 503 509 521 523 541
547 557 563 569 571 577 587 593 599 601 607 613 617 619 631 641 643 647 653 659
661 673 677 683 691 701 709 719 727 733 739 743 751 757 761 769 773 787 797 809
811 821 823 827 829 839 853 857 859 863 877 881 883 887 907 911 919 929 937 941
/;
sub nth_prime {
  my $n = shift;
  return 0 if $n <= 0;
  die "Out of range for fake nth_prime: $n" unless defined $small_primes[$n-1];
  $small_primes[$n-1];
}

my @pn_primorials = qw/
1
2
6
30
210
2310
30030
510510
9699690
223092870
6469693230
200560490130
7420738134810
304250263527210
13082761331670030
614889782588491410
32589158477190044730
1922760350154212639070
117288381359406970983270
7858321551080267055879090
557940830126698960967415390
40729680599249024150621323470
3217644767340672907899084554130
267064515689275851355624017992790
23768741896345550770650537601358310
2305567963945518424753102147331756070
232862364358497360900063316880507363070
23984823528925228172706521638692258396210
2566376117594999414479597815340071648394470
279734996817854936178276161872067809674997230
31610054640417607788145206291543662493274686990
/;

my @factorials = (qw/
1
1
2
6
24
120
720
5040
40320
362880
3628800
39916800
479001600
6227020800
87178291200
1307674368000
20922789888000
355687428096000
6402373705728000
121645100408832000
2432902008176640000
51090942171709440000
1124000727777607680000
25852016738884976640000
620448401733239439360000
15511210043330985984000000
403291461126605635584000000
10888869450418352160768000000
304888344611713860501504000000
8841761993739701954543616000000
265252859812191058636308480000000
/);

plan tests =>   1    # factorial
              + 2    # primorial and pn_primorial
              + 2;   # extra primorial tests

{
  my @fact = map { factorial($_) }  0 .. $#factorials;
  is_deeply( \@fact, \@factorials, "factorial 0 .. $#factorials" );
}

{
  my @prim   = map { primorial(nth_prime($_)) }  0 .. $#pn_primorials;
  my @pnprim = map { pn_primorial($_)         }  0 .. $#pn_primorials;
  is_deeply(\@prim, \@pn_primorials, "primorial(nth(...)) 0 - $#pn_primorials");
  is_deeply(\@pnprim, \@pn_primorials, "pn_primorial(...) 0 - $#pn_primorials");
}

is( primorial(100), '2305567963945518424753102147331756070', "primorial(100)");

is(
    primorial(541),
    '4711930799906184953162487834760260422020574773409675520188634839616415335845034221205289256705544681972439104097777157991804380284218315038719444943990492579030720635990538452312528339864352999310398481791730017201031090',
    "primorial(541)"
  );