search_a12.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. // Compilation:
  2. // g++ -march=native -Ofast -lgmp search_a12.cpp -o x
  3. #include <gmp.h>
  4. #include <iostream>
  5. using namespace std;
  6. typedef unsigned long long int u64;
  7. static bool primality_pretest(u64 k) {
  8. if (!(k % 3) || !(k % 5) || !(k % 7) || !(k % 11) ||
  9. !(k % 13) || !(k % 17) || !(k % 19) || !(k % 23)
  10. ) {
  11. return false;
  12. }
  13. return true;
  14. }
  15. static bool probprime(u64 k, mpz_t n) {
  16. mpz_set_ui(n, k);
  17. return mpz_probab_prime_p(n, 0);
  18. }
  19. static bool is_chernick(int n, u64 m, mpz_t z) {
  20. u64 t = 9 * m;
  21. for (int i = 2; i <= n - 2; i++) {
  22. if (!primality_pretest((t << i) + 1)) {
  23. return false;
  24. }
  25. }
  26. if (!probprime(6 * m + 1, z)) {
  27. return false;
  28. }
  29. if (!probprime(12 * m + 1, z)) {
  30. return false;
  31. }
  32. if (!probprime(18 * m + 1, z)) {
  33. return false;
  34. }
  35. for (int i = 2; i <= n - 2; i++) {
  36. if (!probprime((t << i) + 1, z)) {
  37. return false;
  38. }
  39. }
  40. return true;
  41. }
  42. int main() {
  43. mpz_t z;
  44. mpz_inits(z, NULL);
  45. // k = 24237176657 (for n = 12)
  46. // when done, check the range from k = 38637176656 to 40237176657 (checked)
  47. // m = 31023586121600 (for n = 11)
  48. // m = 3208386195840 (for n = 10)
  49. //~ Tested up to k = 25000000000
  50. //~ Tested up to k = 26000000000
  51. //~ Tested up to k = 27000000000
  52. // ....
  53. //~ Tested up to k = 5384481556571
  54. // For all n > 5, m is a multiple of 5.
  55. cout << is_chernick(10, 3208386195840, z) << endl;
  56. cout << is_chernick(11, 31023586121600, z) << endl;
  57. cout << is_chernick(11, 2138939853538560, z) << endl;
  58. cout << "\n";
  59. // sanity checks (all three must be 0)
  60. cout << is_chernick(11, 3208386195840, z) << endl;
  61. cout << is_chernick(12, 31023586121600, z) << endl;
  62. cout << is_chernick(12, 2138939853538560, z) << endl;
  63. cout << "\n";
  64. //~ u64 from = 6269000000000+1;
  65. //~ u64 from = 1;
  66. //~ u64 from = 3481312975;
  67. //u64 from = 145454545454545;
  68. //~ u64 from = 145466000000000;
  69. u64 from = 162947348711;
  70. int n = 12;
  71. int t = n - 4;
  72. u64 mul = (5*11);
  73. // Make sure we don't overflow
  74. cout << "Test: " << (from * mul * (1 << (n - 4)) * 9 * (1 << (n - 5)) + 1) << endl;
  75. cout << "Test: " << (((((from * mul) << t) * 9) << (n - 5)) + 1) << endl;
  76. // Make sure mpz works
  77. mpz_set_ui(z, (((((from * mul) << t) * 9) << (n - 5)) + 1));
  78. cout << "Tmpz: " << mpz_get_ui(z) << endl;
  79. cout << "\n";
  80. u64 multiplier = mul << t;
  81. // Maximum value of k is about 1563750000000 (n = 12)
  82. // Maximum value of k is about 3127500000000 (n = 11)
  83. // Maximum value of k is about 6255000000000 (n = 10)
  84. // Maximum value of k is about 12510000000000 (n = 9)
  85. for (u64 k = from ; ; k++) {
  86. //~ for (u64 k = 48474353315LL - 200000000; ; k++) {
  87. if (k % 1000000000LL == 0LL) {
  88. cout << "Tested up to k = " << k << " -- where largest p = " << (((multiplier * k * 8LL) << (n - 6)) + 1) << endl;
  89. }
  90. u64 m = k * multiplier;
  91. if (primality_pretest(6 * m + 1) && primality_pretest(12 * m + 1) && primality_pretest(18 * m + 1) && is_chernick(n-4, m, z)) {
  92. cout << "Found k = " << k << " and m = " << m << endl;
  93. //break;
  94. }
  95. }
  96. return 0;
  97. }