-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path23.c
181 lines (151 loc) · 3.8 KB
/
23.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/**
* A perfect number is a number for which the sum of its proper divisors is exactly equal to the number. For example, the sum of the proper divisors of 28 would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28 is a perfect number.
*
* A number n is called deficient if the sum of its proper divisors is less than n and it is called abundant if this sum exceeds n.
*
* As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the smallest number that can be written as the sum of two abundant numbers is 24. By mathematical analysis, it can be shown that all integers greater than 28123 can be written as the sum of two abundant numbers. However, this upper limit cannot be reduced any further by analysis even though it is known that the greatest number that cannot be expressed as the sum of two abundant numbers is less than this limit.
*
* Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers.
*/
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <math.h>
#include "23.h"
int main()
{
// abundant numbers
int *an;
int i, j, count, result;
count = abundant_numbers(28123, &an);
int ints[28123];
for (i = 0; i < 28123; i++) {
ints[i] = i + 1;
}
int ab_sums[28123];
for (i = 0; i < 28123; i++) {
ab_sums[i] = 0;
}
for (i = 0; i < count; i++) {
for (j = i; j < count; j++) {
if (an[i] + an[j] < 28123) {
ab_sums[an[i] + an[j]] = 1;
}
}
}
result = 0;
for (i = 0; i < 28123; i++) {
if (!ab_sums[i]) {
result += i;
}
}
printf("result: %d\n", result);
free(an);
printf("sod(28): %d\n", sum_of_proper_divisors(28));
return 0;
}
// finds abundant numbers with value <= n
int abundant_numbers(int n, int **result)
{
*result = malloc(n * sizeof(int));
(*result)[0] = 12; // 12 is smallest abundant number
// result index
int ri = 1;
int i;
for (i = 14; i < n; i++) // since 13 is prime
{
if (classify_number(i) == 1) {
(*result)[ri++] = i;
}
}
*result = realloc(*result, ri * sizeof(int));
return ri;
}
// 1: abundant
// 0: perfect
// -1: deficient
int classify_number(int n)
{
// int *divs;
// int proper_count = divisors(n, &divs) - 1;
// int sum = array_sum(proper_count, divs);
int sum = sum_of_proper_divisors(n);
if (sum > n) {
return 1;
} else if (sum == n) {
return 0;
} else
return -1;
}
int array_sum(int len, int arr[])
{
int result = 0;
int i;
for (i = 0; i < len; i++) {
result += arr[i];
}
return result;
}
// finds divisors of n. remember to free *result
int divisors(int n, int **result)
{
int limit = sqrt(n) + 1;
*result = malloc(2 * limit * sizeof(int)); // upper limit of the for loop below
int result_index = 0;
int i, temp;
for (i = 1; i < limit; i++) {
if (n % i == 0) {
(*result)[result_index++] = i;
temp = n / i;
if (temp != i) {
(*result)[result_index++] = temp;
}
}
}
*result = realloc(*result, result_index * sizeof(int));
qsort(*result, result_index, sizeof(int), compare_ints);
return result_index;
}
int compare_ints(const void *a, const void *b)
{
int *arg1 = (int *) a;
int *arg2 = (int *) b;
if (*arg1 < *arg2) {
return -1;
} else if (*arg1 == *arg2) {
return 0;
} else
return 1;
}
int sum_of_divisors(int n)
{
int sum = 1;
int p = 2;
int j;
while (p * p <= n && n > 1) {
if (n % p == 0) {
j = p * p;
n = n / p;
while (n % p == 0) {
j = j * p;
n = n / p;
}
sum = sum * (j - 1);
sum = sum / (p - 1);
}
if (p == 2) {
p = 3;
} else {
p += 2;
}
}
if (n > 1) {
sum = sum * (n + 1);
}
return sum;
}
int sum_of_proper_divisors(int n)
{
return sum_of_divisors(n) - n;
}