136 Singleton difference.pl 1021 B

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. #!/usr/bin/perl
  2. # Daniel "Trizen" Șuteu
  3. # License: GPLv3
  4. # Date: 12 August 2017
  5. # https://github.com/trizen
  6. # https://projecteuler.net/problem=136
  7. # Runtime: 1 min, 25 sec
  8. use 5.010;
  9. use strict;
  10. use warnings;
  11. use ntheory qw(divisors forprimes);
  12. sub has_unique_solution {
  13. my ($n) = @_;
  14. my @divisors = divisors($n);
  15. my $count = 0;
  16. foreach my $divisor (@divisors) {
  17. last if $divisor > sqrt($n);
  18. my $p = $divisor;
  19. my $q = $n / $divisor;
  20. my $k = $q + $p;
  21. ($k % 4 == 0) ? ($k >>= 2) : next;
  22. my $x1 = 3*$k - sqrt(4 * $k**2 - $n);
  23. my $x2 = 3*$k + sqrt(4 * $k**2 - $n);
  24. if (($x1 - 2*$k) > 0) {
  25. ++$count;
  26. }
  27. if ($x1 != $x2) {
  28. return 0 if ++$count > 1;
  29. }
  30. }
  31. return ($count == 1);
  32. }
  33. my $count = 0;
  34. my $limit = 50e6 - 1;
  35. forprimes {
  36. if ($_ % 4 == 3) {
  37. ++$count;
  38. }
  39. } $limit;
  40. foreach my $n (1 .. $limit>>2) {
  41. has_unique_solution(4*$n) && ++$count;
  42. }
  43. say $count;