/** * A brute force, single threaded find of "perfect" numbers. * It also finds minusone and plusone numbers * (although I have never see it actually find a plusone). * * A perfect number is one whose factors, excluding itself, * add up to the number. For example, 6. * * Perfect numbers are rare. * https://en.wikipedia.org/wiki/List_of_perfect_numbers * * @author gtowell * Created: April 2021 * **/ #include #include #include typedef struct { int count; int data[1000]; } accumul; /** * Print utility for the accumul struct * @param head -- a string to print * @param dat -- an instance of the structure * **/ void pres(char *head, accumul dat) { for (int i = 0; i < dat.count; i++) printf("%s %2d %d\n", head, i, dat.data[i]); } accumul perfect; // perfect numbers accumul minusone; // number one less than perfect accumul plusone; // numbers one more than perfect long curr = 1; // the next number to check for perfection /** * Check the next number for perfection * Uses the global curr rather than receiving the number as a param * If the number is perfect, store it in the global perfect structure * **/ void checkit() { int val = curr++; int j = sqrt(val); int sm = 1; for (int k = 2; k <= j; k++) { int div = val / k; if (k*div == val) { sm += k; if (k!=div) sm += div; } } //printf("%d %d\n", i, sm); if (sm == val) { perfect.data[perfect.count++] = val; } if (sm==(val-1)) { minusone.data[minusone.count++] = val; } if (sm==(val+1)) { plusone.data[plusone.count++] = val; } } int main(int argc, char const *argv[]) { perfect.count = 0; plusone.count = 0; minusone.count = 0; curr = atol(argv[1]); long max = atol(argv[2]); while (1) { checkit(); if (curr > max) break; } pres("perfect", perfect); pres("minusone", minusone); pres("plusone", plusone); printf("Complete %s %s\n", argv[1], argv[2]); return 0; }