#include <iostream>
#include <cassert>
#include <cmath>
using namespace std;
//完全数,真因子之和等于该数
//1.需要判断一个数是否为因子
//2.需要获得所有真因子之和
//3.需要判断是否是完全数
bool is_factor(int factor, int num)
{
return num % factor == 0;
}
static int add_factor(int factor, int num)
{
return factor + num / factor;
}
static int cal_aliquot_sum(int num)
{
int sum = 1;
for (int i = 2; i <= (int)sqrt((double)num); i++)
{
if (is_factor(i, num))
{
sum += add_factor(i, num);
}
}
return sum;
}
int aliquot_sum(int num)
{
int sum = 0;
if (num > 0)
{
sum = cal_aliquot_sum(num);
}
return sum;
}
bool is_perfect(int num)
{
return aliquot_sum(num) == num;
}
bool is_abundant(int num)
{
return aliquot_sum(num) > num;
}
bool is_deficient(int num)
{
return aliquot_sum(num) < num;
}
/* ------------------------------- */
void test_1_is_factor_of_10()
{
assert(is_factor(1, 10));
}
void test_10_is_factor_of_10()
{
assert(is_factor(10, 10));
}
void test_3_is_not_factor_of_10()
{
assert(!is_factor(3, 10));
}
void test_aliquot_sum_of_6()
{
assert(6 == aliquot_sum(6));
}
void test_aliquot_sum_of_28()
{
int sum = 1 + 28 + 2 + 14 + 4 + 7 - 28;
assert(sum == aliquot_sum(28));
}
void test_aliquot_sum_of_negative()
{
assert(0 == aliquot_sum(-20));
}
void test_aliquot_sum_of_max_int()
{
assert(1 == aliquot_sum(2147483647));
}
void test_the_first_five_perfect()
{
assert(is_perfect(6));
assert(is_perfect(28));
assert(is_perfect(496));
assert(is_perfect(8128));
assert(is_perfect(33550336));
}
static const int PERFECT_NUMS[] = {6, 28, 496, 8128, 33550336};
bool find_num_in(int num, const int *perfects, int size)
{
bool found = false;
int i = 0;
while (!found && i < size)
{
if (perfects[i++] == num)
{
found = true;
}
}
return found;
}
void test_non_perfect()
{
int size = sizeof(PERFECT_NUMS) / sizeof(int);
for (int i = 2; i < 10000; i++)
{
if (find_num_in(i, PERFECT_NUMS, size))
{
assert(is_perfect(i));
}
else
{
assert(!is_perfect(i));
}
}
}
int main()
{
test_1_is_factor_of_10();
test_10_is_factor_of_10();
test_3_is_not_factor_of_10();
test_aliquot_sum_of_6();
test_aliquot_sum_of_28();
test_aliquot_sum_of_negative();
test_aliquot_sum_of_max_int();
test_the_first_five_perfect();
test_non_perfect();
return 0;
}