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 qw/ ramanujan_sum hclassno ramanujan_tau /;

#my $extra = defined $ENV{EXTENDED_TESTING} && $ENV{EXTENDED_TESTING};
#my $use64 = Math::Prime::Util::prime_get_config->{'maxbits'} > 32;
#my $usexs = Math::Prime::Util::prime_get_config->{'xs'};
#my $usegmp= Math::Prime::Util::prime_get_config->{'gmp'};
#$use64 = 0 if $use64 && 18446744073709550592 == ~0;

my %hclassno = (
      -3 => 0,
       0 => -1,
       1 => 0,
       2 => 0,
       3 => 4,
       4 => 6,
       7 => 12,
       8 => 12,
      11 => 12,
      12 => 16,
      20 => 24,
      23 => 36,
      39 => 48,
      47 => 60,
      71 => 84,
     163 => 12,
     427 => 24,
     907 => 36,
    1555 => 48,
    6307 => 96,
   20563 => 156,
   30067 => 168,
   31243 => 192,
   34483 => 180,
    4031 => 1008,
);

my %rtau = (
       0 => 0,
       1 => 1,
       2 => -24,
       3 => 252,
       4 => -1472,
       5 => 4830,
      53 => -1596055698,
     106 => 38305336752,
     243 => 13400796651732,
   16089 => "12655813883111729342208",
);

plan tests => 0 + 3  # Ramanujan sum
                + scalar(keys %hclassno)
                + scalar(keys %rtau);

###### Ramanujan Sum
{
  is( ramanujan_sum(0, 34), 0, "Ramanujan Sum  c_0(34) = 0" );
  is( ramanujan_sum(34, 0), 0, "Ramanujan Sum  c_34(0)" );
  # A 30x30 grid of c_k(n)
  my @expect = (qw/1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 -1 2 -1 -1 2 -1 -1 2 -1 -1 2 -1 -1 2 -1 -1 2 -1 -1 2 -1 -1 2 -1 -1 2 -1 -1 2 0 -2 0 2 0 -2 0 2 0 -2 0 2 0 -2 0 2 0 -2 0 2 0 -2 0 2 0 -2 0 2 0 -2 -1 -1 -1 -1 4 -1 -1 -1 -1 4 -1 -1 -1 -1 4 -1 -1 -1 -1 4 -1 -1 -1 -1 4 -1 -1 -1 -1 4 1 -1 -2 -1 1 2 1 -1 -2 -1 1 2 1 -1 -2 -1 1 2 1 -1 -2 -1 1 2 1 -1 -2 -1 1 2 -1 -1 -1 -1 -1 -1 6 -1 -1 -1 -1 -1 -1 6 -1 -1 -1 -1 -1 -1 6 -1 -1 -1 -1 -1 -1 6 -1 -1 0 0 0 -4 0 0 0 4 0 0 0 -4 0 0 0 4 0 0 0 -4 0 0 0 4 0 0 0 -4 0 0 0 0 -3 0 0 -3 0 0 6 0 0 -3 0 0 -3 0 0 6 0 0 -3 0 0 -3 0 0 6 0 0 -3 1 -1 1 -1 -4 -1 1 -1 1 4 1 -1 1 -1 -4 -1 1 -1 1 4 1 -1 1 -1 -4 -1 1 -1 1 4 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 10 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 10 -1 -1 -1 -1 -1 -1 -1 -1 0 2 0 -2 0 -4 0 -2 0 2 0 4 0 2 0 -2 0 -4 0 -2 0 2 0 4 0 2 0 -2 0 -4 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 12 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 12 -1 -1 -1 -1 1 -1 1 -1 1 -1 -6 -1 1 -1 1 -1 1 6 1 -1 1 -1 1 -1 -6 -1 1 -1 1 -1 1 6 1 -1 1 1 -2 1 -4 -2 1 1 -2 -4 1 -2 1 1 8 1 1 -2 1 -4 -2 1 1 -2 -4 1 -2 1 1 8 0 0 0 0 0 0 0 -8 0 0 0 0 0 0 0 8 0 0 0 0 0 0 0 -8 0 0 0 0 0 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 16 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 0 3 0 0 -3 0 0 -6 0 0 -3 0 0 3 0 0 6 0 0 3 0 0 -3 0 0 -6 0 0 -3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 18 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 2 0 -2 0 2 0 -2 0 -8 0 -2 0 2 0 -2 0 2 0 8 0 2 0 -2 0 2 0 -2 0 -8 1 1 -2 1 1 -2 -6 1 -2 1 1 -2 1 -6 -2 1 1 -2 1 1 12 1 1 -2 1 1 -2 -6 1 -2 1 -1 1 -1 1 -1 1 -1 1 -1 -10 -1 1 -1 1 -1 1 -1 1 -1 1 10 1 -1 1 -1 1 -1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 22 -1 -1 -1 -1 -1 -1 -1 0 0 0 4 0 0 0 -4 0 0 0 -8 0 0 0 -4 0 0 0 4 0 0 0 8 0 0 0 4 0 0 0 0 0 0 -5 0 0 0 0 -5 0 0 0 0 -5 0 0 0 0 -5 0 0 0 0 20 0 0 0 0 -5 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 -12 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 12 1 -1 1 -1 0 0 0 0 0 0 0 0 -9 0 0 0 0 0 0 0 0 -9 0 0 0 0 0 0 0 0 18 0 0 0 0 2 0 -2 0 2 0 -2 0 2 0 -2 0 -12 0 -2 0 2 0 -2 0 2 0 -2 0 2 0 12 0 2 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 28 -1 -1 1 2 1 4 -2 -1 1 2 -4 -1 -2 -1 1 -8 1 -1 -2 -1 -4 2 1 -1 -2 4 1 2 1 -1 8/);
  my @got;
  for my $k (1..30) {
    for my $n (1..30) {
      push @got, ramanujan_sum($k, $n);
    }
  }
  is_deeply( \@got, \@expect, "Ramanujan sum c_{1..30}(1..30)" );
}

###### Hurwitz Class Number
while (my($n, $h) = each (%hclassno)) {
  is( hclassno(0 + $n), $h, "H($n) = $h" );
}

###### Ramanujan Tau
while (my($n, $tau) = each (%rtau)) {
  is( ramanujan_tau(0 + $n), $tau, "Ramanujan Tau($n) = $tau" );
}