number_of_representations_as_sum_of_3_triangles.pl 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. #!/usr/bin/perl
  2. # Daniel "Trizen" Șuteu
  3. # Date: 02 March 2018
  4. # https://github.com/trizen
  5. # Compute the number of ordered ways of writing `n` as the sum of 3 triangular numbers.
  6. # See also:
  7. # https://oeis.org/A008443
  8. # https://projecteuler.net/problem=621
  9. use 5.020;
  10. use strict;
  11. use warnings;
  12. use ntheory qw(factor_exp);
  13. use experimental qw(signatures);
  14. sub count_sums_of_two_squares ($n) {
  15. my $count = 4;
  16. foreach my $p (factor_exp($n)) {
  17. my $r = $p->[0] % 4;
  18. if ($r == 3) {
  19. $p->[1] % 2 == 0 or return 0;
  20. }
  21. if ($r == 1) {
  22. $count *= $p->[1] + 1;
  23. }
  24. }
  25. return $count;
  26. }
  27. sub count_triangular_sums ($n) {
  28. my $count = 0;
  29. my $limit = (sqrt(8 * $n + 1) - 1) / 2;
  30. for my $u (0 .. $limit) {
  31. my $z = ($n - $u * ($u + 1) / 2) * 8 + 1;
  32. $count += count_sums_of_two_squares($z + 1);
  33. }
  34. return $count / 4;
  35. }
  36. say count_triangular_sums(10**6); #=> 2106
  37. say count_triangular_sums(10**9); #=> 62760
  38. say count_triangular_sums(31415926535); #=> 263556