hcn.pl 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. #!/usr/bin/perl
  2. # Daniel "Trizen" Șuteu
  3. # Date: 27 June 2019
  4. # https://github.com/trizen
  5. # Print the n-th highly composite number, using data generated by Achim Flammenkamp.
  6. # See also:
  7. # https://oeis.org/A321995 -- Indices of highly composite numbers A002182 which are between a twin prime pair.
  8. # https://oeis.org/A108951 -- Completely multiplicative with a(p) = p# for prime p, where x# is the primorial A034386(x).
  9. # https://oeis.org/A002182 -- Highly composite numbers, definition (1): where d(n), the number of divisors of n (A000005), increases to a record.
  10. use 5.020;
  11. use strict;
  12. use warnings;
  13. use Math::GMPz;
  14. use ntheory qw(:all);
  15. use POSIX qw(ULONG_MAX);
  16. use IO::Uncompress::Bunzip2;
  17. use experimental qw(signatures);
  18. local $| = 1;
  19. prime_precalc(1e7);
  20. # "HCN.bz2" was generated by Achim Flammenkamp, and is available at:
  21. # http://wwwhomes.uni-bielefeld.de/achim/HCN.bz2
  22. my $z = IO::Uncompress::Bunzip2->new("HCN.bz2");
  23. my $from = shift(@ARGV) // die "usage: perl $0 [from] [to=from]\n";
  24. my $to = shift(@ARGV) // $from;
  25. if ($from < 0) {
  26. die "error: $from must be a positive integer\n";
  27. }
  28. if ($to < $from) {
  29. die "error: $to must be >= $from\n";
  30. }
  31. my $tmp = Math::GMPz->new(1);
  32. while (defined(my $line = $z->getline())) {
  33. if ($. < $from) {
  34. next;
  35. }
  36. my @fields = split(' ', $line);
  37. my $omega = shift(@fields);
  38. my @primes = (($omega > 0) ? @{primes(nth_prime($omega))} : ());
  39. my $prod = Math::GMPz->new(1);
  40. while (@primes) {
  41. my $k = shift(@fields) // die "unexpected error: $line\n";
  42. my $e = 1;
  43. if ($k =~ /^(\d+)\^(\d+)\z/) {
  44. $k = $1;
  45. $e = $2;
  46. }
  47. for (1 .. $e) {
  48. my $p = shift(@primes);
  49. if ($k == 1) {
  50. Math::GMPz::Rmpz_mul_ui($prod, $prod, $p);
  51. }
  52. elsif ($p**$k < ULONG_MAX) {
  53. Math::GMPz::Rmpz_mul_ui($prod, $prod, powint($p, $k));
  54. }
  55. else {
  56. Math::GMPz::Rmpz_ui_pow_ui($tmp, $p, $k);
  57. Math::GMPz::Rmpz_mul($prod, $prod, $tmp);
  58. }
  59. }
  60. }
  61. if ($. >= $from) {
  62. say "$. $prod";
  63. last if $. >= $to;
  64. }
  65. }