Algorithms_in_C 1.0.0
Set of algorithms implemented in C.
Loading...
Searching...
No Matches
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_LIMIT   (uint64_t)1e9
 modulo limit
 
#define MAX_LENGTH   5000
 chunk size of array allocation
 

Functions

char is_in (uint64_t N, uint64_t *D, uint64_t L)
 Check if a number is present in given array. More...
 
uint64_t get_divisors (uint64_t N, uint64_t *D)
 Get all integer divisors of a number. More...
 
uint64_t sigma2 (uint64_t N)
 compute sum of squares of all integer factors of a number More...
 
uint64_t sigma (uint64_t N)
 sum of squares of factors of numbers from 1 thru N More...
 
int main (int argc, char **argv)
 Main function. More...
 

Detailed Description

Problem 401 solution - Sum of squares of divisors

Author
Krishna Vedala

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
48{
49 uint64_t q, r;
50 int64_t i, num = 0;
51
52 if (N == 1)
53 {
54 D[0] = 1;
55 return 1;
56 }
57
58 // search till sqrt(N)
59 // because after this, the pair of divisors will repeat themselves
60 for (i = 1; i * i <= N + 1; i++)
61 {
62 r = N % i; // get reminder
63
64 // reminder = 0 if 'i' is a divisor of 'N'
65 if (r == 0)
66 {
67 q = N / i;
68 if (!is_in(i, D, num)) // if divisor was already stored
69 {
70 D[num] = i;
71 num++;
72 }
73 if (!is_in(q, D, num)) // if divisor was already stored
74 {
75 D[num] = q;
76 num++;
77 }
78 }
79
80 if (num == MAX_LENGTH)
81 { // limit of array reached, allocate more space
82 D = (uint64_t *)realloc(D, MAX_LENGTH * sizeof(uint64_t) << 1);
83 }
84 }
85 return num;
86}
char is_in(uint64_t N, uint64_t *D, uint64_t L)
Check if a number is present in given array.
Definition: sol1.c:28
#define MAX_LENGTH
chunk size of array allocation
Definition: sol1.c:18
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 {
33 if (D[i] == N)
34 {
35 return 1;
36 }
37 }
38 return 0;
39}
Definition: list.h:8

◆ main()

int main ( int  argc,
char **  argv 
)

Main function.

133{
134 uint64_t N = 1000;
135
136 if (argc == 2)
137 {
138 N = strtoll(argv[1], NULL, 10);
139 }
140 else if (argc > 2)
141 {
142 fprintf(stderr, "Wrong number of input arguments!\n");
143 printf("Usage:\t ./sol1.c [N=1000]");
144 return -1;
145 }
146
147 clock_t start_time = clock();
148 uint64_t result = sigma(N);
149 double dtime = clock() - start_time;
150
151 printf("N = %" PRIu64 "\nSum: %" PRIu64 "\n", N, result);
152 printf("Time taken: %.4gms\n", dtime * 1e3 / CLOCKS_PER_SEC);
153
154 return 0;
155}
uint64_t sigma(uint64_t N)
sum of squares of factors of numbers from 1 thru N
Definition: sol1.c:114
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

115{
116 uint64_t s, sum = 0;
117 int64_t i;
118
119#ifdef _OPENMP
120// parallelize on threads
121#pragma omp parallel for reduction(+ : sum)
122#endif
123 for (i = 0; i <= N; i++)
124 {
125 s = sigma2(i);
126 sum += s;
127 }
128 return sum % MOD_LIMIT;
129}
uint64_t sigma2(uint64_t N)
compute sum of squares of all integer factors of a number
Definition: sol1.c:93
#define MOD_LIMIT
modulo limit
Definition: sol1.c:17
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
94{
95 uint64_t sum = 0, L;
96 int64_t i;
97 uint64_t *D = (uint64_t *)malloc(MAX_LENGTH * sizeof(uint64_t));
98
99 L = get_divisors(N, D);
100 for (i = 1; i < L; i++)
101 {
102 uint64_t DD = (D[i] * D[i]) % MOD_LIMIT;
103 sum += DD;
104 }
105
106 free(D);
107 return sum % MOD_LIMIT;
108}
#define malloc(bytes)
This macro replace the standard malloc function with malloc_dbg.
Definition: malloc_dbg.h:18
#define free(ptr)
This macro replace the standard free function with free_dbg.
Definition: malloc_dbg.h:26
uint64_t get_divisors(uint64_t N, uint64_t *D)
Get all integer divisors of a number.
Definition: sol1.c:47
Here is the call graph for this function: