Zumkeller numbers are the set of numbers whose divisors can be partitioned into two disjoint sets that sum to the same value. Each sum must contain divisor values that are not in the other sum, and all of the divisors must be in one or the other. There are no restrictions on how the divisors are partitioned, only that the two partition sums are equal.



E.G.
 6 is a Zumkeller number; The divisors {1 2 3 6} can be partitioned into two groups {1 2 3} and {6} that both sum to 6.
 10 is not a Zumkeller number; The divisors {1 2 5 10} can not be partitioned into two groups in any way that will both sum to the same value.
 12 is a Zumkeller number; The divisors {1 2 3 4 6 12} can be partitioned into two groups {1 3 4 6} and {2 12} that both sum to 14.


Even Zumkeller numbers are common; odd Zumkeller numbers are much less so. For values below 10^6, there is at least one Zumkeller number in every 12 consecutive integers, and the vast majority of them are even. The odd Zumkeller numbers are very similar to the list from the task Abundant odd numbers; they are nearly the same except for the further restriction that the abundance (A(n) = sigma(n) - 2n), must be even: A(n) mod 2 == 0



Task

 Write a routine (function, procedure, whatever) to find Zumkeller numbers.
 Use the routine to find and display here, on this page, the first 220 Zumkeller numbers.
 Use the routine to find and display here, on this page, the first 40 odd Zumkeller numbers.
 Optional, stretch goal: Use the routine to find and display here, on this page, the first 40 odd Zumkeller numbers that don't end with 5.


See Also

 OEIS:A083207 - Zumkeller numbers to get an impression of different partitions OEIS:A083206 Zumkeller partitions
 OEIS:A174865 - Odd Zumkeller numbers


Related Tasks

 Abundant odd numbers
 Abundant, deficient and perfect number classifications
 Proper divisors , Factors of an integer
Module Module1
    Function GetDivisors(n As Integer) As List(Of Integer)
        Dim divs As New List(Of Integer) From {
            1, n
        }
        Dim i = 2
        While i * i <= n
            If n Mod i = 0 Then
                Dim j = n \ i
                divs.Add(i)
                If i <> j Then
                    divs.Add(j)
                End If
            End If
            i += 1
        End While
        Return divs
    End Function
 
    Function IsPartSum(divs As List(Of Integer), sum As Integer) As Boolean
        If sum = 0 Then
            Return True
        End If
        Dim le = divs.Count
        If le = 0 Then
            Return False
        End If
        Dim last = divs(le - 1)
        Dim newDivs As New List(Of Integer)
        For i = 1 To le - 1
            newDivs.Add(divs(i - 1))
        Next
        If last > sum Then
            Return IsPartSum(newDivs, sum)
        End If
        Return IsPartSum(newDivs, sum) OrElse IsPartSum(newDivs, sum - last)
    End Function
 
    Function IsZumkeller(n As Integer) As Boolean
        Dim divs = GetDivisors(n)
        Dim sum = divs.Sum()
        REM if sum is odd can't be split into two partitions with equal sums
        If sum Mod 2 = 1 Then
            Return False
        End If
        REM if n is odd use 'abundant odd number' optimization
        If n Mod 2 = 1 Then
            Dim abundance = sum - 2 * n
            Return abundance > 0 AndAlso abundance Mod 2 = 0
        End If
        REM if n and sum are both even check if there's a partition which totals sum / 2
        Return IsPartSum(divs, sum \ 2)
    End Function
 
    Sub Main()
        Console.WriteLine("The first 220 Zumkeller numbers are:")
        Dim i = 2
        Dim count = 0
        While count < 220
            If IsZumkeller(i) Then
                Console.Write("{0,3} ", i)
                count += 1
                If count Mod 20 = 0 Then
                    Console.WriteLine()
                End If
            End If
            i += 1
        End While
        Console.WriteLine()
 
        Console.WriteLine("The first 40 odd Zumkeller numbers are:")
        i = 3
        count = 0
        While count < 40
            If IsZumkeller(i) Then
                Console.Write("{0,5} ", i)
                count += 1
                If count Mod 10 = 0 Then
                    Console.WriteLine()
                End If
            End If
            i += 2
        End While
        Console.WriteLine()
 
        Console.WriteLine("The first 40 odd Zumkeller numbers which don't end in 5 are:")
        i = 3
        count = 0
        While count < 40
            If i Mod 10 <> 5 AndAlso IsZumkeller(i) Then
                Console.Write("{0,7} ", i)
                count += 1
                If count Mod 8 = 0 Then
                    Console.WriteLine()
                End If
            End If
            i += 2
        End While
    End Sub
End Module