Algorithms_in_C  1.0.0
Set of algorithms implemented in C.
sol1.c File Reference

Problem 401 solution - Sum of squares of divisors More...

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <inttypes.h>
Include dependency graph for sol1.c:

Macros

#define __STDC_FORMAT_MACROS
 
#define MOD   (uint64_t)1e9
 
#define MAX_L   5000
 

Functions

char is_in (uint64_t N, uint64_t *D, uint64_t L)
 
uint64_t get_divisors (uint64_t N, uint64_t *D)
 
uint64_t sigma2 (uint64_t N)
 
uint64_t sigma (uint64_t N)
 
int main (int argc, char **argv)
 

Detailed Description

Problem 401 solution - Sum of squares of divisors

Author
Krishna Vedala

Macro Definition Documentation

◆ MAX_L

#define MAX_L   5000

chunk size of array allocation

◆ MOD

#define MOD   (uint64_t)1e9

modulo limit

Function Documentation

◆ get_divisors()

uint64_t get_divisors ( uint64_t  N,
uint64_t *  D 
)

Get all integer divisors of a number

Parameters
[in]Nnumber to find divisors for
[out]Darray to store divisors in
Returns
number of divisors found
44 {
45  uint64_t q, r;
46  int64_t i, num = 0;
47 
48  if (N == 1)
49  {
50  D[0] = 1;
51  return 1;
52  }
53 
54  // search till sqrt(N)
55  // because after this, the pair of divisors will repeat themselves
56  for (i = 1; i * i <= N + 1; i++)
57  {
58  r = N % i; // get reminder
59 
60  // reminder = 0 if 'i' is a divisor of 'N'
61  if (r == 0)
62  {
63  q = N / i;
64  if (!is_in(i, D, num)) // if divisor was already stored
65  {
66  D[num] = i;
67  num++;
68  }
69  if (!is_in(q, D, num)) // if divisor was already stored
70  {
71  D[num] = q;
72  num++;
73  }
74  }
75 
76  if (num == MAX_L) // limit of array reached, allocate more space
77  D = (uint64_t *)realloc(D, MAX_L * sizeof(uint64_t) << 1);
78  }
79  return num;
80 }
Here is the call graph for this function:

◆ is_in()

char is_in ( uint64_t  N,
uint64_t *  D,
uint64_t  L 
)

Check if a number is present in given array

Parameters
[in]Nnumber to check
[in]Darray to check
[in]Llength of array
Returns
1 if present
0 if absent
29 {
30  uint64_t i;
31  for (i = 0; i < L; i++)
32  if (D[i] == N)
33  return 1;
34  return 0;
35 }

◆ main()

int main ( int  argc,
char **  argv 
)

Main function

127 {
128  uint64_t N = 1000;
129 
130  if (argc == 2)
131  N = strtoll(argv[1], NULL, 10);
132  else if (N > 2)
133  {
134  fprintf(stderr, "Wrong number of input arguments!\n");
135  printf("Usage:\t ./sol1.c [N=1000]");
136  return -1;
137  }
138 
139  clock_t start_time = clock();
140  uint64_t result = sigma(N);
141  double dtime = clock() - start_time;
142 
143  printf("N = %" PRIu64 "\nSum: %" PRIu64 "\n", N, result);
144  printf("Time taken: %.4gms\n", dtime * 1e3 / CLOCKS_PER_SEC);
145 
146  return 0;
147 }
Here is the call graph for this function:

◆ sigma()

uint64_t sigma ( uint64_t  N)

sum of squares of factors of numbers from 1 thru N

109 {
110  uint64_t s, sum = 0;
111  int64_t i;
112 
113 #ifdef _OPENMP
114 // parallelize on threads
115 #pragma omp parallel for reduction(+ : sum)
116 #endif
117  for (i = 0; i <= N; i++)
118  {
119  s = sigma2(i);
120  sum += s;
121  }
122  return sum % MOD;
123 }
Here is the call graph for this function:

◆ sigma2()

uint64_t sigma2 ( uint64_t  N)

compute sum of squares of all integer factors of a number

Parameters
[in]N
Returns
sum of squares
88 {
89  uint64_t sum = 0, L;
90  int64_t i;
91  uint64_t *D = (uint64_t *)malloc(MAX_L * sizeof(uint64_t));
92 
93  L = get_divisors(N, D);
94  for (i = 1; i < L; i++)
95  {
96  uint64_t DD = (D[i] * D[i]) % MOD;
97  sum += DD;
98  }
99 
100  free(D);
101  return sum % MOD;
102 }
Here is the call graph for this function:
L
Definition: list.h:8
MOD
#define MOD
Definition: sol1.c:17
sigma2
uint64_t sigma2(uint64_t N)
Definition: sol1.c:87
get_divisors
uint64_t get_divisors(uint64_t N, uint64_t *D)
Definition: sol1.c:43
MAX_L
#define MAX_L
Definition: sol1.c:18
N
#define N
Definition: sol1.c:109
is_in
char is_in(uint64_t N, uint64_t *D, uint64_t L)
Definition: sol1.c:28
sigma
uint64_t sigma(uint64_t N)
Definition: sol1.c:108