Advertisement
joric

lattice.cpp

Oct 10th, 2021 (edited)
630
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.78 KB | None | 0 0
  1. /*
  2.  
  3. Problem:
  4. Given circle with center at (0,0) and integer n [1..10^8].
  5. Find radius r [1..n] with the most number of points with integral coordinates on the circumference of the circle
  6. Examples: n = 2, output = 1; n = 5, output = 5; n = 10000, output = 5525
  7.  
  8. References:
  9. https://oeis.org/A046109 Number of lattice points (x,y) on the circumference of a circle of radius n with center at (0,0)
  10. https://oeis.org/A088959 (Lowest numbers which are d-Pythagorean decomposable, essentially a solution to the problem)
  11. https://stackoverflow.com/questions/2267146/what-is-the-fastest-integer-factorization-algorithm
  12. https://math.stackexchange.com/questions/2069171/fast-way-to-find-pythagorean-decompositions
  13.  
  14. Solution with a precalculated lookup table (python 3, same sequence as https://oeis.org/A088959):
  15. import bisect
  16. n=int(input())
  17. k=[1, 5, 25, 65, 325, 1105, 5525, 27625, 32045, 160225, 801125, 1185665, 5928325, 29641625, 48612265]
  18. print(k[bisect.bisect(k,n)-1])
  19.  
  20. */
  21.  
  22.  
  23. #include <bits/stdc++.h>
  24. using namespace std;
  25.  
  26. #define uint unsigned __int32
  27. uint *factors;
  28. // const uint MAX_F = 134217728; // 2^27
  29.  
  30. const uint MAX_F = 50000000;
  31.  
  32. void buildFactors() {
  33.     factors = new (nothrow) uint[(MAX_F + 1) * 2]; // 4 * 2 * 2^27 = 2^30 = 1GB
  34.  
  35.     if (factors == NULL)
  36.         return; // not able to allocate enough free memory
  37.  
  38.     int i;
  39.     for (i = 0; i < (MAX_F + 1) * 2; i++)
  40.         factors[i] = 0;
  41.  
  42.     // Sieve of Eratosthenese
  43.     factors[1 * 2] = 1;
  44.     factors[1 * 2 + 1] = 1;
  45.     for (i = 2; i * i <= MAX_F; i++) {
  46.         for (; factors[i * 2] && i * i <= MAX_F; i++)
  47.             ;
  48.         factors[i * 2] = 1;
  49.         factors[i * 2 + 1] = i;
  50.         for (int j = 2; i * j <= MAX_F; j++) {
  51.             factors[i * j * 2] = i;
  52.             factors[i * j * 2 + 1] = j;
  53.         }
  54.     }
  55.     for (; i <= MAX_F; i++) {
  56.         for (; i <= MAX_F && factors[i * 2]; i++)
  57.             ;
  58.         if (i > MAX_F)
  59.             return;
  60.         factors[i * 2] = 1;
  61.         factors[i * 2 + 1] = i;
  62.     }
  63. }
  64.  
  65. uint *factor(uint x, int &factorCount) {
  66.     if (x > MAX_F) {
  67.         factorCount = -1;
  68.         return NULL;
  69.     }
  70.     static uint tmp[70];
  71.     uint at = x;
  72.     int i = 0;
  73.     while (factors[at * 2] > 1) {
  74.         tmp[i++] = factors[at * 2];
  75.         //cout << "at:" << at << " tmp:" << tmp[i - 1] << endl;
  76.         at = factors[at * 2 + 1];
  77.     }
  78.     if (i == 0) {
  79.         //cout << "at:" << x << " tmp:1" << endl;
  80.         tmp[i++] = 1;
  81.         tmp[i++] = x;
  82.     } else {
  83.         //cout << "at:" << at << " tmp:1" << endl;
  84.         tmp[i++] = at;
  85.     }
  86.     factorCount = i;
  87.     return tmp;
  88. }
  89.  
  90. int a(uint n) {
  91.     int r = 1;
  92.     int size;
  93.     uint *f = factor(n, size);
  94.  
  95.     for (int i=0; i<size; i++) {
  96.         if (f[i] == 1)
  97.             continue;
  98.  
  99.         int count = 1;
  100.         while (i < size - 1 && f[i] == f[i + 1]) {
  101.             count++;
  102.             i++;
  103.         }
  104.  
  105.         if ((f[i] % 4)==1) {
  106.             r *= 2*count + 1;
  107.         }
  108.     }
  109.  
  110.     return 4*r;
  111. }
  112.  
  113. int main() {
  114.     time_t start = time(0);
  115.  
  116.     cout << "Loading factors lookup table" << endl;
  117.     buildFactors();
  118.     if (factors == NULL) {
  119.         cerr << "Need 1GB block of free memory" << endl;
  120.         return 0;
  121.     }
  122.  
  123.     time_t end = time(0);
  124.  
  125.     cout << "time: " << difftime(end, start) << " sec." << endl;
  126.  
  127.     uint c = 0;
  128.  
  129.     uint maxr = 0;
  130.     uint p0 = 0;
  131.     uint p = 0;
  132.  
  133.     start = time(0);
  134.  
  135.     int n = 100000000;
  136.  
  137.     for (uint i=1; i<=n; i++) {
  138.         p = a(i);
  139.         if (p>p0) {
  140.             p0 = p;
  141.             maxr = i;
  142.             cout << i << ":" << p << endl;
  143.         }
  144.     }
  145.  
  146.     end = time(0);
  147.     uint diff = difftime(end, start);
  148.  
  149.     cout << "time: " << diff << " sec. " << n/diff << " rad/sec." << endl;
  150.  
  151.     delete[] factors;
  152. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement