Change to new GCD function

This commit is contained in:
Alexander Rosenberg 2022-09-03 04:09:36 -07:00
parent 4af0adf350
commit b7ed7e230a
Signed by: Zander671
GPG Key ID: 5FD0394ADBD72730

150
main.c
View File

@ -111,13 +111,12 @@ static void print_arg_error(const char *arg);
static void print_help_and_exit(void); static void print_help_and_exit(void);
static void print_version_and_exit(void); static void print_version_and_exit(void);
static void print_info_and_exit(void); static void print_info_and_exit(void);
static unsigned long find_gcf(unsigned long *nums, size_t len);
static unsigned long *find_prime_factors(unsigned long n, size_t *out_len);
static void initialize_modules(void); static void initialize_modules(void);
static unsigned long gcd(unsigned long n1, unsigned long n2);
static unsigned long find_module_refresh_time(void);
static void set_refresh_time(void); static void set_refresh_time(void);
static void signal_handler(int signum); static void signal_handler(int signum);
static void setup_signals(void); static void setup_signals(void);
static unsigned long find_module_refresh_gcf(void);
static unsigned long timespec_to_miliseconds(struct timespec *ts); static unsigned long timespec_to_miliseconds(struct timespec *ts);
static void miliseconds_to_timespec(unsigned long ms, struct timespec *out_ts); static void miliseconds_to_timespec(unsigned long ms, struct timespec *out_ts);
static void do_initial_refresh(void); static void do_initial_refresh(void);
@ -431,102 +430,6 @@ static void print_info_and_exit(void) {
qtb_exit(); qtb_exit();
} }
static unsigned long find_gcf(unsigned long *nums, size_t len) {
if (len == 0) { /* gcf(0) = 0 */
return 0;
} else if (len == 1) { /* gcf(n) = n */
return nums[0];
}
/* calculate all prime factors */
unsigned long **prime_factors = NULL;
size_t prime_factors_length = 0;
size_t i;
for (i = 0; i < len; ++i) {
unsigned long *i_prime_factors = find_prime_factors(nums[i], NULL);
prime_factors = qtb_realloc(prime_factors, sizeof(unsigned long *) *
++prime_factors_length);
prime_factors[prime_factors_length - 1] = i_prime_factors;
}
/* find which calculated prime factors are common to all inputs */
unsigned long *common_factors = NULL;
size_t common_factors_length = 0;
unsigned long *j;
/* loop though each factor in prime_factors[0] */
for (j = prime_factors[0]; *j != 0; ++j) {
/* loop though every set of factors except prime_factors[0] */
/* size_t i; */
for (i = 1; i < prime_factors_length; ++i) {
unsigned long *i_prime_factors;
for (i_prime_factors = prime_factors[i]; *i_prime_factors != 0;
++i_prime_factors) {
if (*i_prime_factors == *j) {
*i_prime_factors = 4; /* remove the factor (by setting it to
a composite number) */
goto found_factor;
}
}
/* the factor was not found, therefore we can't add it */
goto dont_add;
/* we found the factor, check the next set of factors */
found_factor:
continue;
}
/* the factor was a common factor, add it */
common_factors = qtb_realloc(
common_factors, sizeof(unsigned long) * ++common_factors_length);
common_factors[common_factors_length - 1] = *j;
/* the factor was not a common factor */
dont_add:
continue;
}
/* qtb_free sets of factors */
/* size_t i; */
for (i = 0; i < prime_factors_length; ++i) {
qtb_free(prime_factors[i]);
}
qtb_free(prime_factors);
/* finally, calculate the gcf */
unsigned long gcf = 1;
/* size_t i; */
for (i = 0; i < common_factors_length; ++i) {
gcf *= common_factors[i];
}
qtb_free(common_factors);
return gcf;
}
/* return value will be 0 terminated. if out_len is not NULL,
it's value will be set to the number of primes found (length of return value
- 1) */
static unsigned long *find_prime_factors(unsigned long n, size_t *out_len) {
unsigned long *out_arr = NULL;
size_t arr_len = 0;
while (n % 2 == 0) {
out_arr = qtb_realloc(out_arr, sizeof(unsigned long) * ++arr_len);
out_arr[arr_len - 1] = 2;
n /= 2;
}
unsigned long i;
for (i = 3; i <= sqrtl(n); i += 2) {
while (n % i == 0) {
out_arr =
qtb_realloc(out_arr, sizeof(unsigned long) * ++arr_len);
out_arr[arr_len - 1] = i;
n /= i;
}
}
if (n > 2) {
out_arr = qtb_realloc(out_arr, sizeof(unsigned long) * ++arr_len);
out_arr[arr_len - 1] = n;
}
out_arr = qtb_realloc(out_arr, sizeof(unsigned long) * arr_len);
out_arr[arr_len] = 0;
if (out_len) {
*out_len = arr_len;
}
return out_arr;
}
static void initialize_modules() { static void initialize_modules() {
int has_error = FALSE; int has_error = FALSE;
size_t i; size_t i;
@ -552,11 +455,42 @@ static void initialize_modules() {
} }
} }
unsigned long gcd(unsigned long n1, unsigned long n2) {
if (n1 == 0) {
return n2;
}
return gcd(n2 % n1, n1);
}
unsigned long find_module_refresh_time() {
size_t i;
size_t ignore_index;
size_t result;
for (i = 0; i < global_module_count; ++i) {
if (!modules[i].disabled && modules[i].refresh_time != NO_REFRESH) {
result = modules[i].refresh_time;
ignore_index = i;
}
}
for (i = 0; i < global_module_count; ++i) {
if (i == ignore_index) {
continue;
}
if (!modules[i].disabled && modules[i].refresh_time != NO_REFRESH) {
result = gcd(result, modules[i].refresh_time);
}
if (result == 1) {
break;
}
}
return result;
}
static void set_refresh_time() { static void set_refresh_time() {
#ifdef REFRESH_TIME #ifdef REFRESH_TIME
unsigned long refresh_ms = REFRESH_TIME; unsigned long refresh_ms = REFRESH_TIME;
#else #else
unsigned long refresh_ms = find_module_refresh_gcf(); unsigned long refresh_ms = find_module_refresh_time();
if (refresh_ms == 0) { /* if all modules are triggered by signals */ if (refresh_ms == 0) { /* if all modules are triggered by signals */
refresh_ms = HOURS(1); /* refresh once an hour */ refresh_ms = HOURS(1); /* refresh once an hour */
} }
@ -600,22 +534,6 @@ static void setup_signals() {
sigprocmask(SIG_BLOCK, &global_real_time_mask, NULL); sigprocmask(SIG_BLOCK, &global_real_time_mask, NULL);
} }
static unsigned long find_module_refresh_gcf() {
size_t refresh_times_length = 0;
unsigned long *refresh_times = NULL;
size_t i;
for (i = 0; i < global_module_count; ++i) {
if (!modules[i].disabled && modules[i].refresh_time != NO_REFRESH) {
refresh_times = qtb_realloc(
refresh_times, sizeof(unsigned long) * ++refresh_times_length);
refresh_times[refresh_times_length - 1] = modules[i].refresh_time;
}
}
unsigned long gcf = find_gcf(refresh_times, refresh_times_length);
qtb_free(refresh_times);
return gcf;
}
static unsigned long timespec_to_miliseconds(struct timespec *ts) { static unsigned long timespec_to_miliseconds(struct timespec *ts) {
return (ts->tv_sec * 1000) + (ts->tv_nsec / 1000000); return (ts->tv_sec * 1000) + (ts->tv_nsec / 1000000);
} }