generate_carmichael_with_p==q_mod_12_db.pl 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #!/usr/bin/perl
  2. # Generate Carmichael that have all prime factors p congruent to a constant k modulo 12.
  3. # (takes around 11 minutes to complete)
  4. use 5.020;
  5. use strict;
  6. use warnings;
  7. use Math::GMPz;
  8. use ntheory qw(:all);
  9. use Math::Prime::Util::GMP;
  10. use experimental qw(signatures);
  11. use List::Util qw(uniq);
  12. eval { require GDBM_File };
  13. my $cache_db = "cache/factors.db";
  14. dbmopen(my %db, $cache_db, 0444)
  15. or die "Can't create/access database <<$cache_db>>: $!";
  16. my %table;
  17. use IO::Handle;
  18. open my $fh, '>>', 'special_carmichael.txt';
  19. $fh->autoflush(1);
  20. say ":: Generating... Please wait...";
  21. my %seen_p;
  22. {
  23. my $nm1 = Math::GMPz::Rmpz_init();
  24. my $pm1 = Math::GMPz::Rmpz_init();
  25. sub my_is_carmichael_faster ($n, $factors) {
  26. Math::GMPz::Rmpz_set_str($nm1, $n, 10);
  27. Math::GMPz::Rmpz_sub_ui($nm1, $nm1, 1);
  28. return if not vecall {
  29. ($_ < ~0) ? Math::GMPz::Rmpz_divisible_ui_p($nm1, $_ - 1) : do {
  30. Math::GMPz::Rmpz_set_str($pm1, $_, 10);
  31. Math::GMPz::Rmpz_sub_ui($pm1, $pm1, 1);
  32. Math::GMPz::Rmpz_divisible_p($nm1, $pm1);
  33. }
  34. }
  35. @$factors;
  36. return 1;
  37. }
  38. }
  39. while (my ($n, $value) = each %db) {
  40. my @factors = uniq(split(' ', $value));
  41. scalar(@factors) >= 5 or next;
  42. my %table;
  43. foreach my $p (@factors) {
  44. if (modint(divint(subint(mulint($p, $p), 1), 2), 12) == 0) {
  45. push @{$table{modint($p, 12)}}, $p;
  46. }
  47. }
  48. foreach my $group (values %table) {
  49. scalar(@$group) >= 4 or next;
  50. my $t = Math::Prime::Util::GMP::vecprod(@$group);
  51. if ($t > ~0 and my_is_carmichael_faster($t, $group)) {
  52. #say $t;
  53. say $fh $t;
  54. }
  55. }
  56. }
  57. say ":: Done...";
  58. close $fh;
  59. dbmclose(%db);