mirror of
https://github.moeyy.xyz/https://github.com/TheAlgorithms/C.git
synced 2023-10-11 15:56:24 +08:00
109 lines
2.3 KiB
C
109 lines
2.3 KiB
C
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <time.h>
|
||
|
#ifdef _OPENMP
|
||
|
#include <omp.h>
|
||
|
#endif
|
||
|
|
||
|
unsigned long MAX_N = 28123;
|
||
|
|
||
|
/**
|
||
|
* Returns:
|
||
|
* -1 if N is deficient
|
||
|
* 1 if N is abundant
|
||
|
* 0 if N is perfect
|
||
|
**/
|
||
|
char get_perfect_number(unsigned long N)
|
||
|
{
|
||
|
unsigned long sum = 1;
|
||
|
char ret = 0;
|
||
|
|
||
|
for (unsigned long i = 2; i * i <= N; i++)
|
||
|
{
|
||
|
if (N % i == 0)
|
||
|
{
|
||
|
sum += i;
|
||
|
unsigned long tmp = N / i;
|
||
|
if (tmp != i)
|
||
|
sum += tmp;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ret = sum == N ? 0 : (sum > N ? 1 : -1);
|
||
|
// #ifdef DEBUG
|
||
|
// printf("%5lu: %5lu : %d\n", N, sum, ret);
|
||
|
// #endif
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Find the next abundant number after N and not including N
|
||
|
**/
|
||
|
unsigned long is_abundant(unsigned long N)
|
||
|
{
|
||
|
return get_perfect_number(N) == 1 ? 1 : 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Find the next abundant number after N and not including N
|
||
|
**/
|
||
|
unsigned long get_next_abundant(unsigned long N)
|
||
|
{
|
||
|
unsigned long i;
|
||
|
for (i = N + 1; !is_abundant(i); i++)
|
||
|
;
|
||
|
return i;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* check if a given number can be represented as a sum
|
||
|
* of two abundant numbers.
|
||
|
* 1 - if yes
|
||
|
* 0 - if not
|
||
|
**/
|
||
|
char is_sum_of_abundant(unsigned long N)
|
||
|
{
|
||
|
for (unsigned long i = get_next_abundant(1); i <= (N >> 1); i = get_next_abundant(i))
|
||
|
if (is_abundant(N - i))
|
||
|
{
|
||
|
#ifdef DEBUG
|
||
|
printf("\t%4lu + %4lu = %4lu\n", i, N - i, N);
|
||
|
#endif
|
||
|
return 1;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int main(int argc, char **argv)
|
||
|
{
|
||
|
unsigned long sum = 0;
|
||
|
if (argc == 2)
|
||
|
MAX_N = strtoul(argv[1], NULL, 10);
|
||
|
|
||
|
#ifdef _OPENMP
|
||
|
printf("Using OpenMP parallleization with %d threads\n", omp_get_max_threads());
|
||
|
#else
|
||
|
printf("Not using parallleization!\n");
|
||
|
#endif
|
||
|
|
||
|
clock_t start_time = clock();
|
||
|
#ifdef _OPENMP
|
||
|
#pragma omp parallel for reduction(+ \
|
||
|
: sum) schedule(runtime)
|
||
|
#endif
|
||
|
for (unsigned long i = 1; i <= MAX_N; i++)
|
||
|
{
|
||
|
if (!is_sum_of_abundant(i))
|
||
|
sum += i;
|
||
|
// if (i % 100 == 0)
|
||
|
// printf("... %5lu: %8lu\r", i, sum);
|
||
|
}
|
||
|
clock_t end_time = clock();
|
||
|
|
||
|
printf("\nTime taken for final sum: %.4g ms\n", 1e3 * (end_time - start_time) / CLOCKS_PER_SEC);
|
||
|
printf("Sum of numbers that cannot be represented as sum of two abundant numbers : %lu\n", sum);
|
||
|
|
||
|
return 0;
|
||
|
}
|