Advertisement
Guest User

primes.c

a guest
May 4th, 2018
189
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.85 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <inttypes.h>
  4.  
  5. #define K 8  // primality test iterations
  6.  
  7. static uint64_t
  8. rand64(void)
  9. {
  10.     static uint64_t s[] = {
  11.         UINT64_C(0x1fc7807c9aa37949), UINT64_C(0x9e8029c0558cfca3)
  12.     };
  13.     uint64_t s0 = s[0];
  14.     uint64_t s1 = s[1];
  15.     uint64_t result = s0 + s1;
  16.     s1 ^= s0;
  17.     s[0] = ((s0 << 55) | (s0 >> 9)) ^ s1 ^ (s1 << 14);
  18.     s[1] = (s1 << 36) | (s1 >> 28);
  19.     return result;
  20. }
  21.  
  22. static uint64_t
  23. modmult(uint64_t b, uint64_t e, uint64_t m)
  24. {
  25.     uint64_t sum = 0;
  26.     if (b == 0 || e < m / b)
  27.         return (b * e) % m;
  28.     while (e > 0) {
  29.         if (e % 2 == 1)
  30.             sum = (sum + b) % m;
  31.         b = (2 * b) % m;
  32.         e /= 2;
  33.     }
  34.     return sum;
  35. }
  36.  
  37. static uint64_t
  38. modexp(uint64_t b, uint64_t e, uint64_t m)
  39. {
  40.     uint64_t product = 1;
  41.     uint64_t pseq = b % m;
  42.     while (e > 0) {
  43.         if (e % 2 == 1)
  44.             product = modmult(product, pseq, m);
  45.         pseq = modmult(pseq, pseq, m);
  46.         e /= 2;
  47.     }
  48.     return product;
  49. }
  50.  
  51. static int
  52. iscomposite(uint64_t n, uint64_t d, int r)
  53. {
  54.     uint64_t a = 2 + rand64() % (n - 3);
  55.     if (modexp(a, d, n) == 1)
  56.         return 0;
  57.     for (int i = 0; i < r; i++)
  58.         if (modexp(a, (UINT64_C(1) << i) * d, n) == n - 1)
  59.             return 0;
  60.     return 1;
  61. }
  62.  
  63. static int
  64. isprime(uint64_t n)
  65. {
  66.     switch (n) {
  67.         case 0:
  68.         case 1:
  69.             return 0;
  70.         case 2:
  71.         case 3:
  72.             return 1;
  73.     }
  74.     int r = 0;
  75.     uint64_t d = n - 1;
  76.     for (; d % 2 == 0; r++)
  77.         d /= 2;
  78.     for (int i = 0; i < K; i++)
  79.         if (iscomposite(n, d, r))
  80.             return 0;
  81.     return 1;
  82. }
  83.  
  84. static uint64_t
  85. extract(char grid[64][64], int n, int x, int y, int d, int len)
  86. {
  87.     static const int dir[] = {
  88.         +0, -1, +1, -1, +1, +0, +1, +1, +0, +1, -1, +1, -1, +0, -1, -1
  89.     };
  90.     uint64_t value = 0;
  91.     for (int i = 0; i < len; i++) {
  92.         int tx = x + i * dir[d * 2 + 0];
  93.         int ty = y + i * dir[d * 2 + 1];
  94.         if (tx < 0 || tx >= n || ty < 0 || ty >= n)
  95.             return -1;
  96.         value = value * 10 + grid[ty][tx];
  97.     }
  98.     return value;
  99. }
  100.  
  101. static uint64_t
  102. hash64(uint64_t x)
  103. {
  104.     uint64_t z = x + UINT64_C(0x9e3779b97f4a7c15);
  105.     z = (z ^ (z >> 30)) * UINT64_C(0xbf58476d1ce4e5b9);
  106.     z = (z ^ (z >> 27)) * UINT64_C(0x94d049bb133111eb);
  107.     return z ^ (z >> 31);
  108. }
  109.  
  110. static void
  111. insert(uint64_t *table, uint64_t mask, uint64_t value)
  112. {
  113.     uint64_t hash = hash64(value) & mask;
  114.     while (table[hash]) {
  115.         if (table[hash] == value)
  116.             return;
  117.         hash = (hash + 1) & mask;
  118.     }
  119.     table[hash] = value;
  120. }
  121.  
  122. int
  123. main(void)
  124. {
  125.     int n;
  126.     char line[67];
  127.     char grid[64][64] = {{0}};
  128.  
  129.     fgets(line, sizeof(line), stdin);
  130.     n = atoi(line);
  131.     for (int y = 0; y < n; y++) {
  132.         fgets(line, sizeof(line), stdin);
  133.         for (int x = 0; x < n; x++)
  134.             grid[y][x] = line[x] - '0';
  135.     }
  136.  
  137.     static uint64_t table[64L * 1024]; /* size must be power of 2 */
  138.     uint64_t mask = sizeof(table) / sizeof(*table) - 1;
  139.  
  140.     #pragma omp parallel for schedule(dynamic)
  141.     for (int y = 0; y < n; y++) {
  142.         for (int x = 0; x < n; x++) {
  143.             for (int d = 0; d < 8; d++) { /* 8 directions */
  144.                 for (int len = 1; len < 19; len++) { /* 64-bit max len */
  145.                     uint64_t value = extract(grid, n, x, y, d, len);
  146.                     if (value == (uint64_t)-1)
  147.                         break;
  148.                     if (isprime(value)) {
  149.                         #pragma omp critical
  150.                         insert(table, mask, value);
  151.                     }
  152.                 }
  153.             }
  154.         }
  155.     }
  156.  
  157.     for (size_t i = 0; i < sizeof(table) / sizeof(*table); i++)
  158.         if (table[i])
  159.             printf("%" PRIu64 "\n", table[i]);
  160. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement