0003.c 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdint.h>
  4. #include <stdbool.h>
  5. struct primes_da {
  6. uint64_t *data;
  7. uint64_t size;
  8. uint64_t cap;
  9. };
  10. bool isprime(struct primes_da *primes, uint64_t n);
  11. void primes_fill(struct primes_da *primes);
  12. int
  13. main(int argc, const char **argv)
  14. {
  15. uint64_t res = 0;
  16. uint64_t i = 0;
  17. uint64_t target = 600851475143;
  18. uint64_t prime = 0;
  19. ldiv_t dm = {0};
  20. struct primes_da primes = {0};
  21. primes.cap = 256;
  22. primes.data = calloc(primes.cap, sizeof(uint64_t));
  23. primes.size = 0;
  24. primes_fill(&primes);
  25. while ( i < target ) {
  26. if ( i >= primes.size ) {
  27. primes.cap = primes.cap * 2;
  28. primes.data = realloc(primes.data,
  29. primes.cap * sizeof(uint64_t));
  30. primes_fill(&primes);
  31. }
  32. prime = primes.data[i];
  33. dm = ldiv((int64_t)target, (int64_t)prime);
  34. if ( isprime(&primes, (uint64_t)dm.quot) ) {
  35. if ( prime > res ) {
  36. res = prime;
  37. }
  38. }
  39. if ( dm.rem != 0 ) {
  40. ++i;
  41. continue;
  42. }
  43. if ( prime > res ) {
  44. res = prime;
  45. }
  46. target = (uint64_t)dm.quot;
  47. }
  48. printf("Result = %ld!\n", res);
  49. (void) argc; (void) argv;
  50. return 0;
  51. }
  52. bool
  53. isprime(struct primes_da *primes, uint64_t n)
  54. {
  55. uint64_t i = 0;
  56. if ( (n & 1) == 0 ) {
  57. return false;
  58. }
  59. if ( primes != NULL ) {
  60. if ( n < primes->data[primes->size-1] ) {
  61. for ( i = 0; i < primes->size; ++i ) {
  62. if ( n == primes->data[i] ) {
  63. return true;
  64. }
  65. }
  66. return false;
  67. }
  68. }
  69. for ( i = 2; i < n; ++i ) {
  70. if ( (n % i) == 0 ) {
  71. return false;
  72. }
  73. }
  74. return true;
  75. }
  76. void
  77. primes_fill(struct primes_da *primes)
  78. {
  79. uint64_t i = primes->size;
  80. if ( i == 0 ) {
  81. i = 2;
  82. }
  83. for ( ; primes->size < primes->cap; ++i ) {
  84. if ( isprime(NULL, i) ) {
  85. primes->data[primes->size++] = i;
  86. }
  87. }
  88. }