pomerance_generate_smooth_primes.pl 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. #!/usr/bin/perl
  2. # Generate primes that satisfy Pomerance's conditions for being factors of a PSW pseudoprime.
  3. use 5.020;
  4. use warnings;
  5. use experimental qw(signatures);
  6. use Math::GMPz;
  7. use ntheory qw(:all);
  8. sub check_valuation ($n, $p) {
  9. ($n % $p) != 0;
  10. }
  11. sub smooth_numbers ($limit, $primes) {
  12. my @h = (1);
  13. foreach my $p (@$primes) {
  14. say "Prime: $p";
  15. foreach my $n (@h) {
  16. if ($n * $p <= $limit and check_valuation($n, $p)) {
  17. push @h, $n * $p;
  18. }
  19. }
  20. }
  21. return \@h;
  22. }
  23. my @smooth_primes;
  24. foreach my $p (@{primes(307)}) {
  25. $p % 4 == 3 or next;
  26. push @smooth_primes, $p;
  27. }
  28. say "Smooth primes count: ", scalar(@smooth_primes);
  29. say "Smooth primes: ", join(', ', @smooth_primes);
  30. my $h = smooth_numbers((~0)>>2, \@smooth_primes);
  31. say "\nFound: ", scalar(@$h), " terms";
  32. #~ foreach my $n (@$h) {
  33. #~ my $t = 2*$n;
  34. #~ if ($t+2 < ~0 and is_prime($t+1) and is_smooth($t+2, 10000)) {
  35. #~ is_square_free(($t+2)>>2) || next;
  36. #~ next if not vecall { $_ % 4 == 3 } factor(($t+2)>>2);
  37. #~ say $t+1;
  38. #~ }
  39. #~ }
  40. foreach my $n (@$h) {
  41. my $t = 4*$n;
  42. if ($t < ~0 and is_prime($t-1) and is_smooth($t-2, 10000)) {
  43. is_square_free(($t-2)>>1) || next;
  44. next if not vecall { $_ % 4 == 1 } factor(($t-2)>>1);
  45. say $t-1;
  46. }
  47. }