Use if statements

Perfect Numbers
Perfect Numbers in C#
using System;
using System.Linq;

public enum Classification
{
    Perfect,
    Abundant,
    Deficient
}

public class PerfectNumbers
{
    public static Classification Classify(int number)
    {
        if (number < 1)
            throw new ArgumentOutOfRangeException(nameof(number));

        var sumOfFactors = Enumerable.Range(1, number / 2)
            .Where(factor => number % factor == 0)
            .Sum();

        if (sumOfFactors < number)
            return Classification.Deficient;

        if (sumOfFactors > number)
            return Classification.Abundant;

        return Classification.Perfect;
    }
}

The first step is to check the number for validity:

if (number < 1)
    throw new ArgumentOutOfRangeException(nameof(number));

The next step is to calculate the sum of the number's factors. A factor is a number that you can divide another number with and not end up with a remainder, which we can check using the modulo (%) operator: number % factor == 0.

We then need to decide which numbers could possibly be factors. For the lower bound, we can use 1, as that is always the smallest factor. For the upper bound, we can leverage the fact that the second lowest factor is 2, which means that any numbers greater than number / 2 cannot be factors.

We can use the Enumerable.Range() method to iterate over the possible factors, then use Where() to select only valid factors and then finally sum them via the Sum() method:

var sumOfFactors = Enumerable.Range(1, number / 2)
    .Where(factor => number % factor == 0)
    .Sum();

Then finally we can apply the logic to classify the perfect number via some if statements:

if (sumOfFactors < number)
    return Classification.Deficient;

if (sumOfFactors > number)
    return Classification.Abundant;

return Classification.Perfect;

Shortening

You could use the ternary operator to replace the if statements:

return sumOfFactors < number ? Classification.Deficient :
       sumOfFactors > number ? Classification.Abundant :
       Classification.Perfect;

Combining Where and Sum vs. using Sum only

Instead of using Where and then Sum we could actually implement this by using Sum only. We can provide the Sum with a lambda that tells it to keep every number that is a factor and use a 0 in place of every number that isn't, effectively disregarding it when summing:

var sum = Enumerable.Range(1, number - 1)
    .Sum(n => number % n == 0 ? n : 0);

This also uses the aforementioned ternary operator.

24th Apr 2024 · Found it useful?