Task: Abundant, deficient and perfect number classifications


C++: #include <iostream>
#include <algorithm>
#include <vector>

std::vector<int> findProperDivisors ( int n ) {
   std::vector<int> divisors ;
   for ( int i = 1 ; i < n / 2 + 1 ; i++ ) {
      if ( n % i == 0 ) 
	 divisors.push_back( i ) ;
   }
   return divisors  ;
}

int main( ) {
   std::vector<int> deficients , perfects , abundants , divisors ;
   for ( int n = 1 ; n < 20001 ; n++ ) {
      divisors = findProperDivisors( n ) ;
      int sum = std::accumulate( divisors.begin( ) , divisors.end( ) , 0 ) ;
      if ( sum < n ) {
	 deficients.push_back( n ) ;
      }
      if ( sum == n ) {
	 perfects.push_back( n ) ;
      }
      if ( sum > n ) {
	 abundants.push_back( n ) ;
      }
   }
   std::cout << "Deficient : " << deficients.size( ) << std::endl ;
   std::cout << "Perfect   : " << perfects.size( ) << std::endl ;
   std::cout << "Abundant  : " << abundants.size( ) << std::endl ;
   return 0 ;
}


C#: using System;
using System.Linq;

public class Program
{
    public static void Main()
    {
        int abundant, deficient, perfect;
        var sw = System.Diagnostics.Stopwatch.StartNew();
        ClassifyNumbers.UsingSieve(20000, out abundant, out deficient, out perfect); sw.Stop();
        Console.WriteLine($"Abundant: {abundant}, Deficient: {deficient}, Perfect: {perfect}  {sw.Elapsed.TotalMilliseconds} ms");
        sw.Restart();
        ClassifyNumbers.UsingOptiDivision(20000, out abundant, out deficient, out perfect);
        Console.WriteLine($"Abundant: {abundant}, Deficient: {deficient}, Perfect: {perfect}  {sw.Elapsed.TotalMilliseconds} ms");
        sw.Restart();
        ClassifyNumbers.UsingDivision(20000, out abundant, out deficient, out perfect);
        Console.WriteLine($"Abundant: {abundant}, Deficient: {deficient}, Perfect: {perfect}  {sw.Elapsed.TotalMilliseconds} ms");
    }
}

public static class ClassifyNumbers
{
    
    public static void UsingSieve(int bound, out int abundant, out int deficient, out int perfect) {
        abundant = perfect = 0;
        
        int[] sum = new int[bound + 1];
        for (int divisor = 1; divisor <= bound >> 1; divisor++)
            for (int i = divisor << 1; i <= bound; i += divisor)
                sum[i] += divisor;
        for (int i = 1; i <= bound; i++) {
            if (sum[i] > i) abundant++;
            else if (sum[i] == i) perfect++;
        }
        deficient = bound - abundant - perfect;
    }

    
    public static void UsingOptiDivision(int bound, out int abundant, out int deficient, out int perfect) {
        abundant = perfect = 0; int sum = 0;
        for (int i = 2, d, r = 1; i <= bound; i++) {
            if ((d = r * r - i) < 0) r++;
            for (int x = 2; x < r; x++) if (i % x == 0) sum += x + i / x;
            if (d == 0) sum += r;
            switch (sum.CompareTo(i)) { case 0: perfect++; break; case 1: abundant++; break; }
            sum = 1;
        }
        deficient = bound - abundant - perfect;
    }

    
    public static void UsingDivision(int bound, out int abundant, out int deficient, out int perfect) {
        abundant = perfect = 0;
        for (int i = 2; i <= bound; i++) {
            int sum = Enumerable.Range(1, (i + 1) / 2)
                .Where(div => i % div == 0).Sum();
            switch (sum.CompareTo(i)) {
                case 0: perfect++; break;
                case 1: abundant++; break;
            }
        }
        deficient = bound - abundant - perfect;
    }
}