784 Reciprocal Pairs.pl 889 B

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. #!/usr/bin/perl
  2. # Reciprocal Pairs
  3. # https://projecteuler.net/problem=784
  4. # Runtime: 1 hour and 10 minutes.
  5. # See version 2 for a faster method.
  6. use 5.020;
  7. use ntheory qw(:all);
  8. use experimental qw(signatures);
  9. local $| = 1;
  10. sub F ($n) {
  11. my $total = 0;
  12. foreach my $a (1 .. $n) {
  13. if ($a % 1000 == 0) {
  14. printf("[%.2f%%] Processing...\r", $a / $n * 100);
  15. }
  16. my %seen;
  17. foreach my $d (divisors($a * $a - 1)) {
  18. $d > $a or next;
  19. foreach my $b (allsqrtmod(1, $d)) {
  20. $a < $b or next;
  21. my $inv = invmod($a, $b);
  22. if (defined($inv) and $inv == invmod($b, $a)) {
  23. next if $seen{$b}++;
  24. $total += $a + $b;
  25. }
  26. }
  27. }
  28. }
  29. print "\n";
  30. return $total;
  31. }
  32. say F(5);
  33. say F(100);
  34. say F(2 * 1e6);