Guest User

Gilad Barkan's divisor find converted to C

a guest
Nov 3rd, 2018
192
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 1.31 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <inttypes.h>
  3. #include <stdio.h>
  4.  
  5. static int is_divisible_recursive(const uint64_t  shared[], const size_t  shareds,
  6.                                   const uint64_t  k,        size_t        i)
  7. {
  8.     /* k need not reduced further */
  9.     if (k < 100000)
  10.         return 0;
  11.  
  12.     /* Tail recursion converted to a loop */
  13.     for (; i < shareds; i++)
  14.         if (!(k % shared[i]))
  15.             if (is_divisible_recursive(shared, shareds, k / shared[i], i))
  16.                 return 1;
  17.  
  18.     /* no more relevant divisors */
  19.     return k <= 150000;
  20. }
  21.  
  22. static inline int is_divisible(const uint64_t  n)
  23. {
  24.     uint64_t  shared[388]; /* Divisors shared by n and our candidate divisors */
  25.     size_t    shareds = 0;
  26.     uint64_t  d;
  27.  
  28.     /* Trivial tests first. */
  29.     if (n < 100000)
  30.         return 0;
  31.     else
  32.     if (n <= 150000)
  33.         return 1;
  34.  
  35.     /* Find all divisors of n, 2 <= n <= sqrt(150000) = 387. */
  36.     for (d = 2; d <= 387; d++)
  37.         if (!(n % d))
  38.             shared[shareds++] = d;
  39.  
  40.     /* Recursive search. */
  41.     return is_divisible_recursive(shared, shareds, n, 0);
  42. }
  43.  
  44. int main(void)
  45. {
  46.     uint64_t  n = 0;
  47.     uint64_t  i;
  48.  
  49.     for (i = 1; i <= 500000; i++)
  50.         n += is_divisible(i);
  51.  
  52.     printf("%" PRIu64 "\n", n);
  53.     return EXIT_SUCCESS;
  54. }
Add Comment
Please, Sign In to add comment