621 Expressing an integer as the sum of triangular numbers.pl 863 B

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. #!/usr/bin/perl
  2. # Daniel "Trizen" Șuteu
  3. # Date: 02 March 2018
  4. # https://github.com/trizen
  5. # https://projecteuler.net/problem=621
  6. # Runtime: ~39 seconds.
  7. use 5.020;
  8. use strict;
  9. use warnings;
  10. use ntheory qw(factor_exp);
  11. use experimental qw(signatures);
  12. sub count_sums_of_two_squares ($n) {
  13. my $count = 4;
  14. foreach my $p (factor_exp($n)) {
  15. my $r = $p->[0] % 4;
  16. if ($r == 3) {
  17. $p->[1] % 2 == 0 or return 0;
  18. }
  19. if ($r == 1) {
  20. $count *= $p->[1] + 1;
  21. }
  22. }
  23. return $count;
  24. }
  25. sub count_triangular_sums ($n) {
  26. my $count = 0;
  27. my $limit = (sqrt(8 * $n + 1) - 1) / 2;
  28. for my $u (0 .. $limit) {
  29. my $z = ($n - $u * ($u + 1) / 2) * 8 + 1;
  30. $count += count_sums_of_two_squares($z + 1);
  31. }
  32. return $count / 4;
  33. }
  34. say count_triangular_sums(17526 * 10**9);