Task: Zumkeller numbers



C#: using System;
using System.Collections.Generic;
using System.Linq;

namespace ZumkellerNumbers {
    class Program {
        static List<int> GetDivisors(int n) {
            List<int> divs = new List<int> {
                1, n
            };
            for (int i = 2; i * i <= n; i++) {
                if (n % i == 0) {
                    int j = n / i;
                    divs.Add(i);
                    if (i != j) {
                        divs.Add(j);
                    }
                }
            }
            return divs;
        }

        static bool IsPartSum(List<int> divs, int sum) {
            if (sum == 0) {
                return true;
            }
            var le = divs.Count;
            if (le == 0) {
                return false;
            }
            var last = divs[le - 1];
            List<int> newDivs = new List<int>();
            for (int i = 0; i < le - 1; i++) {
                newDivs.Add(divs[i]);
            }
            if (last > sum) {
                return IsPartSum(newDivs, sum);
            }
            return IsPartSum(newDivs, sum) || IsPartSum(newDivs, sum - last);
        }

        static bool IsZumkeller(int n) {
            var divs = GetDivisors(n);
            var sum = divs.Sum();
            
            if (sum % 2 == 1) {
                return false;
            }
            
            if (n % 2 == 1) {
                var abundance = sum - 2 * n;
                return abundance > 0 && abundance % 2 == 0;
            }
            
            return IsPartSum(divs, sum / 2);
        }

        static void Main() {
            Console.WriteLine("The first 220 Zumkeller numbers are:");
            int i = 2;
            for (int count = 0; count < 220; i++) {
                if (IsZumkeller(i)) {
                    Console.Write("{0,3} ", i);
                    count++;
                    if (count % 20 == 0) {
                        Console.WriteLine();
                    }
                }
            }

            Console.WriteLine("\nThe first 40 odd Zumkeller numbers are:");
            i = 3;
            for (int count = 0; count < 40; i += 2) {
                if (IsZumkeller(i)) {
                    Console.Write("{0,5} ", i);
                    count++;
                    if (count % 10 == 0) {
                        Console.WriteLine();
                    }
                }
            }

            Console.WriteLine("\nThe first 40 odd Zumkeller numbers which don't end in 5 are:");
            i = 3;
            for (int count = 0; count < 40; i += 2) {
                if (i % 10 != 5 && IsZumkeller(i)) {
                    Console.Write("{0,7} ", i);
                    count++;
                    if (count % 8 == 0) {
                        Console.WriteLine();
                    }
                }
            }
        }
    }
}





Python: from sympy import divisors

from sympy.combinatorics.subsets import Subset

def isZumkeller(n):
    d = divisors(n)
    s = sum(d)
    if not s % 2 and max(d) <= s/2:
        for x in range(1, 2**len(d)):
            if sum(Subset.unrank_binary(x, d).subset) == s/2:
                return True

    return False



def printZumkellers(N, oddonly=False):
    nprinted = 0
    for n in range(1, 10**5):
        if (oddonly == False or n % 2) and isZumkeller(n):
            print(f'{n:>8}', end='')
            nprinted += 1
            if nprinted % 10 == 0:
                print()
            if nprinted >= N:
                return


print("220 Zumkeller numbers:")
printZumkellers(220)
print("\n\n40 odd Zumkeller numbers:")
printZumkellers(40, True)