I'm working on modernizing Rosetta Code's infrastructure. Starting with communications. Please accept this time-limited open invite to RC's Slack.. --Michael Mol (talk) 20:59, 30 May 2020 (UTC)

# Zumkeller numbers

Zumkeller numbers
You are encouraged to solve this task according to the task description, using any language you may know.

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

• 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.

## 11l

Translation of: D
`F getDivisors(n)   V divs = [1, n]   V i = 2   L i * i <= n      I n % i == 0         divs [+]= i          V j = n I/ i         I i != j            divs [+]= j      i++   R divs F isPartSum(divs, sum)   I sum == 0      R 1B    V le = divs.len   I le == 0      R 0B    V last = divs.last   [Int] newDivs   L(i) 0 .< le - 1      newDivs [+]= divs[i]    I last > sum      R isPartSum(newDivs, sum)   E      R isPartSum(newDivs, sum) | isPartSum(newDivs, sum - last) F isZumkeller(n)   V divs = getDivisors(n)   V s = sum(divs)    I s % 2 == 1      R 0B    I n % 2 == 1      V abundance = s - 2 * n      R abundance > 0 & abundance % 2 == 0    R isPartSum(divs, s I/ 2) print(‘The first 220 Zumkeller numbers are:’)V i = 2V count = 0L count < 220   I isZumkeller(i)      print(‘#3 ’.format(i), end' ‘’)      count++      I count % 20 == 0         print()   i++ print("\nThe first 40 odd Zumkeller numbers are:")i = 3count = 0L count < 40   I isZumkeller(i)      print(‘#5 ’.format(i), end' ‘’)      count++      I count % 10 == 0         print()   i += 2 print("\nThe first 40 odd Zumkeller numbers which don't end in 5 are:")i = 3count = 0L count < 40   I i % 10 != 5 & isZumkeller(i)      print(‘#7 ’.format(i), end' ‘’)      count++      I count % 8 == 0         print()   i += 2`
Output:
```The first 220 Zumkeller numbers are:
6  12  20  24  28  30  40  42  48  54  56  60  66  70  78  80  84  88  90  96
102 104 108 112 114 120 126 132 138 140 150 156 160 168 174 176 180 186 192 198
204 208 210 216 220 222 224 228 234 240 246 252 258 260 264 270 272 276 280 282
294 300 304 306 308 312 318 320 330 336 340 342 348 350 352 354 360 364 366 368
372 378 380 384 390 396 402 408 414 416 420 426 432 438 440 444 448 456 460 462
464 468 474 476 480 486 490 492 496 498 500 504 510 516 520 522 528 532 534 540
544 546 550 552 558 560 564 570 572 580 582 588 594 600 606 608 612 616 618 620
624 630 636 640 642 644 650 654 660 666 672 678 680 684 690 696 700 702 704 708
714 720 726 728 732 736 740 744 750 756 760 762 768 770 780 786 792 798 804 810
812 816 820 822 828 832 834 836 840 852 858 860 864 868 870 876 880 888 894 896
906 910 912 918 920 924 928 930 936 940 942 945 948 952 960 966 972 978 980 984

The first 40 odd Zumkeller numbers are:
945  1575  2205  2835  3465  4095  4725  5355  5775  5985
6435  6615  6825  7245  7425  7875  8085  8415  8505  8925
9135  9555  9765 10395 11655 12285 12705 12915 13545 14175
14805 15015 15435 16065 16695 17325 17955 18585 19215 19305

The first 40 odd Zumkeller numbers which don't end in 5 are:
81081  153153  171171  189189  207207  223839  243243  261261
279279  297297  351351  459459  513513  567567  621621  671517
729729  742203  783783  793611  812889  837837  891891  908523
960687  999999 1024947 1054053 1072071 1073709 1095633 1108107
1145529 1162161 1198197 1224531 1270269 1307691 1324323 1378377
```

## AArch64 Assembly

Works with: as version Raspberry Pi 3B version Buster 64 bits
` /* ARM assembly AARCH64 Raspberry PI 3B *//*  program zumkellex641.s   */ /* REMARK 1 : this program use routines in a include file    see task Include a file language arm assembly    for the routine affichageMess conversion10    see at end of this program the instruction include */ /* REMARK 2 : this program is not optimized.    Not search First 40 odd Zumkeller numbers not divisible by 5 */ /*******************************************//* Constantes file                         *//*******************************************//* for this file see task include a file in language AArch64 assembly*/.include "../includeConstantesARM64.inc" .equ NBDIVISORS,             100  /*******************************************//* Structures                               *//********************************************//* structurea area divisors  */    .struct  0div_ident:                     // ident    .struct  div_ident + 8div_flag:                      // value 0, 1 or 2    .struct  div_flag + 8div_fin:/*******************************************//* Initialized data                        *//*******************************************/.dataszMessStartPgm:          .asciz "Program start \n"szMessEndPgm:            .asciz "Program normal end.\n"szMessErrorArea:         .asciz "\033[31mError : area divisors too small.\n"szMessError:             .asciz "\033[31mError  !!!\n" szCarriageReturn:        .asciz "\n" /* datas message display */szMessEntete:            .asciz "The first 220 Zumkeller numbers are:\n"sNumber:                 .space 4*20,' '                         .space 12,' '     // for end of conversionszMessListDivi:          .asciz "Divisors list : \n"szMessListDiviHeap:      .asciz "Heap 1 Divisors list : \n"szMessResult:            .ascii " "sValue:                  .space 12,' '                         .asciz "" szMessEntete1:           .asciz "The first 40 odd Zumkeller numbers are:\n"/*******************************************//* UnInitialized data                      *//*******************************************/.bss .align 4tbDivisors:              .skip div_fin * NBDIVISORS  // area divisorssZoneConv:               .skip 30/*******************************************//*  code section                           *//*******************************************/.text.global main main:                               // program start    ldr x0,qAdrszMessStartPgm       // display start message    bl affichageMess     ldr x0,qAdrszMessEntete         // display message    bl affichageMess    mov x2,#1                       // counter number    mov x3,#0                       // counter zumkeller number    mov x4,#0                       // counter for line display1:    mov x0,x2                       //  number    mov x1,#0                       // display flag    bl testZumkeller    cmp x0,#1                       // zumkeller ?    bne 3f                          // no    mov x0,x2    ldr x1,qAdrsZoneConv            // and convert ascii string    bl conversion10    ldr x0,qAdrsZoneConv            // copy result in display line    ldr x1,qAdrsNumber       lsl x5,x4,#2    add x1,x1,x511:    ldrb w5,[x0],1    cbz w5,12f    strb w5,[x1],1    b 11b12:    add x4,x4,#1    cmp x4,#20    blt 2f    //add x1,x1,#3                  // carriage return at end of display line    mov x0,#'\n'    strb w0,[x1]    mov x0,#0    strb w0,[x1,#1]                 // end of display line    ldr x0,qAdrsNumber              // display result message    bl affichageMess    mov x4,#02:    add x3,x3,#1                    // increment counter3:    add x2,x2,#1                    // increment number    cmp x3,#220                     // end ?    blt 1b     /* raz display line  */    ldr x0,qAdrsNumber     mov x1,' '    mov x2,031:    strb w1,[x0,x2]    add x2,x2,1    cmp x2,4*20    blt 31b     /* odd zumkeller numbers  */    ldr x0,qAdrszMessEntete1    bl affichageMess    mov x2,#1    mov x3,#0    mov x4,#04:    mov x0,x2                       //  number    mov x1,#0                       // display flag    bl testZumkeller    cmp x0,#1    bne 6f    mov x0,x2    ldr x1,qAdrsZoneConv            // and convert ascii string    bl conversion10    ldr x0,qAdrsZoneConv            // copy result in display line    ldr x1,qAdrsNumber       lsl x5,x4,#3    add x1,x1,x541:    ldrb w5,[x0],1    cbz w5,42f    strb w5,[x1],1    b 41b42:    add x4,x4,#1    cmp x4,#8    blt 5f    mov x0,#'\n'    strb w0,[x1]    strb wzr,[x1,#1]    ldr x0,qAdrsNumber              // display result message    bl affichageMess    mov x4,#05:    add x3,x3,#16:    add x2,x2,#2    cmp x3,#40    blt 4b      ldr x0,qAdrszMessEndPgm         // display end message    bl affichageMess    b 100f99:                                 // display error message     ldr x0,qAdrszMessError    bl affichageMess100:                                // standard end of the program    mov x0, #0                      // return code    mov x8, #EXIT                   // request to exit program    svc 0                           // perform system callqAdrszMessStartPgm:        .quad szMessStartPgmqAdrszMessEndPgm:          .quad szMessEndPgmqAdrszMessError:           .quad szMessErrorqAdrszCarriageReturn:      .quad szCarriageReturnqAdrszMessResult:          .quad szMessResultqAdrsValue:                .quad sValueqAdrszMessEntete:          .quad szMessEnteteqAdrszMessEntete1:         .quad szMessEntete1qAdrsNumber:               .quad sNumberqAdrsZoneConv:             .quad sZoneConv/******************************************************************//*     test if number is Zumkeller number                         */ /******************************************************************//* x0 contains the number  *//* x1 contains display flag (<>0: display, 0: no display ) *//* x0 return 1 if Zumkeller number else return 0  */testZumkeller:    stp x1,lr,[sp,-16]!         // save  registers    stp x2,x3,[sp,-16]!         // save  registers    stp x4,x5,[sp,-16]!         // save  registers    stp x6,x7,[sp,-16]!         // save  registers    mov x7,x1                   // save flag    ldr x1,qAdrtbDivisors    bl divisors                 // create area of divisors    cmp x0,#0                   // 0 divisors or error ?    ble 98f    mov x5,x0                   // number of dividers    mov x6,x1                   // number of odd dividers    cmp x7,#1                   // display divisors ?    bne 1f    ldr x0,qAdrszMessListDivi   // yes    bl affichageMess    mov x0,x5    mov x1,#0    ldr x2,qAdrtbDivisors    bl printHeap1:    tst x6,#1                   // number of odd divisors is odd ?    bne 99f    mov x0,x5    mov x1,#0    ldr x2,qAdrtbDivisors    bl sumDivisors              // compute divisors sum    tst x0,#1                   // sum is odd ?    bne 99f                     // yes -> end    lsr x6,x0,#1                // compute sum /2    mov x0,x6                   // x0 contains sum / 2    mov x1,#1                   // first heap    mov x3,x5                   // number divisors    mov x4,#0                   // N° element to start    bl searchHeap    cmp x0,#-2    beq 100f                    // end     cmp x0,#-1    beq 100f                    // end     cmp x7,#1                   // print flag ?    bne 2f    ldr x0,qAdrszMessListDiviHeap    bl affichageMess    mov x0,x5                   // yes print divisors of first heap    ldr x2,qAdrtbDivisors    mov x1,#1    bl printHeap2:    mov x0,#1                   // ok    b 100f98:    mov x0,-1    b 100f99:    mov x0,#0    b 100f100:    ldp x6,x7,[sp],16          // restaur  2 registers    ldp x4,x5,[sp],16          // restaur  2 registers    ldp x2,x3,[sp],16          // restaur  2 registers    ldp x1,lr,[sp],16          // restaur  2 registers    ret                        // return to address lr x30qAdrtbDivisors:          .quad tbDivisorsqAdrszMessListDiviHeap:  .quad szMessListDiviHeap/******************************************************************//*     search sum divisors = sum / 2                             */ /******************************************************************//* x0 contains sum to search *//* x1 contains  flag (1 or 2) *//* x2 contains address of divisors area *//* x3 contains elements number   *//* x4 contains N° element to start *//* x0 return -2  end search *//* x0 return -1  no heap   *//* x0 return 0   Ok *//* recursive routine */searchHeap:    stp x3,lr,[sp,-16]!            // save  registers    stp x4,x5,[sp,-16]!            // save  registers    stp x6,x8,[sp,-16]!            // save  registers1:    cmp x4,x3                   // indice = elements number    beq 99f    lsl x6,x4,#4                // compute element address    add x6,x6,x2    ldr x7,[x6,#div_flag]       // flag equal ?    cmp x7,#0    bne 6f    ldr x5,[x6,#div_ident]    cmp x5,x0                   // element value = remaining amount    beq 7f                      // yes    bgt 6f                      // too large                                 // too less    mov x8,x0                   // save sum    sub x0,x0,x5                // new sum to find    add x4,x4,#1                // next divisors    bl searchHeap               // other search    cmp x0,#0                   // find -> ok    beq 5f     mov x0,x8                   // sum begin    sub x4,x4,#1                // prev divisors    bl razFlags                 // zero in all flags > current element4:    add x4,x4,#1                // last divisors    b 1b5:    str x1,[x6,#div_flag]       // flag -> area element flag    b 100f6:    add x4,x4,#1                // last divisors    b 1b7:    str x1,[x6,#div_flag]       // flag -> area element flag    mov x0,#0                   // search ok    b 100f8:    mov x0,#-1                  // end search     b 100f99:    mov x0,#-2    b 100f100:    ldp x6,x8,[sp],16          // restaur  2 registers    ldp x4,x5,[sp],16          // restaur  2 registers    ldp x3,lr,[sp],16          // restaur  2 registers    ret                        // return to address lr x30/******************************************************************//*     raz flags                                                  */ /******************************************************************//* x0 contains sum to search *//* x1 contains  flag (1 or 2) *//* x2 contains address of divisors area *//* x3 contains elements number   *//* x4 contains N° element to start *//* x5 contains current sum *//* REMARK  : NO SAVE REGISTERS x14 x15 x16 AND LR */razFlags:    mov x14,x41:    cmp x14,x3                   // indice > nb elements ?    bge 100f                     // yes -> end    lsl x15,x14,#4    add x15,x15,x2               // compute address element    ldr x16,[x15,#div_flag]      // load flag    cmp x1,x16                   // equal ?    bne 2f    str xzr,[x15,#div_flag]      // yes -> store 02:    add x14,x14,#1               // increment indice    b 1b                         // and loop100:    ret                          // return to address lr x30/******************************************************************//*     compute sum of divisors                         */ /******************************************************************//* x0 contains elements number *//* x1 contains  flag (0  1 or 2)/* x2 contains address of divisors area/* x0 return divisors sum *//* REMARK  : NO SAVE REGISTERS x13 x14 x15 x16 AND LR */sumDivisors:    mov x13,#0                   // indice    mov x16,#0                   // sum1:    lsl x14,x13,#4               // N° element * 16    add x14,x14,x2    ldr x15,[x14,#div_flag]      // compare flag     cmp x15,x1    bne 2f    ldr x15,[x14,#div_ident]     // load value    add x16,x16,x15              // and add2:    add x13,x13,#1    cmp x13,x0    blt 1b    mov x0,x16                   // return sum100:    ret                          // return to address lr x30/******************************************************************//*     print heap                         */ /******************************************************************//* x0 contains elements number *//* x1 contains  flag (0  1 or 2) *//* x2 contains address of divisors area */printHeap:    stp x2,lr,[sp,-16]!         // save  registers    stp x3,x4,[sp,-16]!         // save  registers    stp x5,x6,[sp,-16]!         // save  registers    stp x1,x7,[sp,-16]!         // save  registers    mov x6,x0    mov x5,x1    mov x3,#0                   // indice1:    lsl x1,x3,#4                // N° element * 16    add x1,x1,x2    ldr x4,[x1,#div_flag]    cmp x4,x5    bne 2f    ldr x0,[x1,#div_ident]    ldr x1,qAdrsValue           // and convert ascii string    bl conversion10    ldr x0,qAdrszMessResult     // display result message    bl affichageMess2:    add x3,x3,#1    cmp x3,x6    blt 1b    ldr x0,qAdrszCarriageReturn    bl affichageMess100:    ldp x1,x8,[sp],16          // restaur  2 registers    ldp x5,x6,[sp],16          // restaur  2 registers    ldp x3,x4,[sp],16          // restaur  2 registers    ldp x2,lr,[sp],16          // restaur  2 registers    ret                        // return to address lr x30/******************************************************************//*     divisors function                         */ /******************************************************************//* x0 contains the number  *//* x1 contains address of divisors area/* x0 return divisors number *//* x1 return counter odd divisors *//* REMARK  : NO SAVE REGISTERS x10 x11 x12 x13 x14 x15 x16 x17 x18 */divisors:    str lr,[sp,-16]!            // save  register LR    cmp x0,#1                   // = 1 ?    ble 98f    mov x17,x0    mov x18,x1    mov x11,#1                  // counter odd divisors    mov x0,#1                   // first divisor = 1    str x0,[x18,#div_ident]    mov x0,#0    str x0,[x18,#div_flag]    tst x17,#1                  // number is odd ?    cinc  x11,x11,ne            // count odd divisors    mov x0,x17                  // last divisor = N    add x10,x18,#16             // store at next element    str x0,[x10,#div_ident]    mov x0,#0    str x0,[x10,#div_flag]     mov x16,#2                  // first divisor    mov x15,#2                  // Counter divisors2:                              // begin loop    udiv x12,x17,x16    msub x13,x12,x16,x17    cmp x13,#0                  // remainder = 0 ?    bne 3f    cmp x12,x16    blt 4f                      // quot<divisor  end    lsl x10,x15,#4              // N° element * 16    add x10,x10,x18             // and add at area begin address    str x12,[x10,#div_ident]    str xzr,[x10,#div_flag]    add x15,x15,#1              // increment counter    cmp x15,#NBDIVISORS         // area maxi ?    bge 99f     tst x12,#1    cinc  x11,x11,ne            // count odd divisors    cmp x12,x16                 // quotient = divisor ?    ble 4f    lsl x10,x15,#4              // N° element * 16    add x10,x10,x18             // and add at area begin address    str x16,[x10,#div_ident]    str xzr,[x10,#div_flag]    add x15,x15,#1              // increment counter    cmp x15,#NBDIVISORS         // area maxi ?    bge 99f     tst x16,#1    cinc  x11,x11,ne            // count odd divisors3:    cmp x12,x16    ble 4f    add x16,x16,#1              // increment divisor    b 2b                        // and loop 4:    mov x0,x15                  // return divisors number    mov x1,x11                  // return count odd divisors    b 100f98:    mov x0,0    b 100f99:                             // error    ldr x0,qAdrszMessErrorArea    bl affichageMess    mov x0,-1100:    ldr lr,[sp],16              // restaur  1 registers    ret                         // return to address lr x30qAdrszMessListDivi:           .quad szMessListDiviqAdrszMessErrorArea:          .quad szMessErrorArea/********************************************************//*        File Include fonctions                        *//********************************************************//* for this file see task include a file in language AArch64 assembly */.include "../includeARM64.inc" `
```Program start
The first 220 Zumkeller numbers are:
6   12  20  24  28  30  40  42  48  54  56  60  66  70  78  80  84  88  90  96
102 104 108 112 114 120 126 132 138 140 150 156 160 168 174 176 180 186 192 198
204 208 210 216 220 222 224 228 234 240 246 252 258 260 264 270 272 276 280 282
294 300 304 306 308 312 318 320 330 336 340 342 348 350 352 354 360 364 366 368
372 378 380 384 390 396 402 408 414 416 420 426 432 438 440 444 448 456 460 462
464 468 474 476 480 486 490 492 496 498 500 504 510 516 520 522 528 532 534 540
544 546 550 552 558 560 564 570 572 580 582 588 594 600 606 608 612 616 618 620
624 630 636 640 642 644 650 654 660 666 672 678 680 684 690 696 700 702 704 708
714 720 726 728 732 736 740 744 750 756 760 762 768 770 780 786 792 798 804 810
812 816 820 822 828 832 834 836 840 852 858 860 864 868 870 876 880 888 894 896
906 910 912 918 920 924 928 930 936 940 942 945 948 952 960 966 972 978 980 984
The first 40 odd Zumkeller numbers are:
945     1575    2205    2835    3465    4095    4725    5355
5775    5985    6435    6615    6825    7245    7425    7875
8085    8415    8505    8925    9135    9555    9765    10395
11655   12285   12705   12915   13545   14175   14805   15015
15435   16065   16695   17325   17955   18585   19215   19305
Program normal end.
```

## AppleScript

On my machine, this takes about 0.28 seconds to perform the two main searches and a further 107 to do the stretch task. However, the latter time can be dramatically reduced to 1.7 seconds with the cheat of knowing beforehand that the first 200 or so odd Zumkellers not ending with 5 are divisible by 63. The "abundant number" optimisation's now used with odd numbers, but the cheat-free running time was only two to three seconds longer without it.

`-- Sum n's proper divisors.on aliquotSum(n)    if (n < 2) then return 0    set sum to 1    set sqrt to n ^ 0.5    set limit to sqrt div 1    if (limit = sqrt) then        set sum to sum + limit        set limit to limit - 1    end if    repeat with i from 2 to limit        if (n mod i is 0) then set sum to sum + i + n div i    end repeat     return sumend aliquotSum -- Return n's proper divisors.on properDivisors(n)    set output to {}     if (n > 1) then        set sqrt to n ^ 0.5        set limit to sqrt div 1        if (limit = sqrt) then            set end of output to limit            set limit to limit - 1        end if        repeat with i from limit to 2 by -1            if (n mod i is 0) then                set beginning of output to i                set end of output to n div i            end if        end repeat        set beginning of output to 1    end if     return outputend properDivisors -- Does a subset of the given list of numbers add up to the target value?on subsetOf:numberList sumsTo:target    script o        property lst : numberList        property someNegatives : false         on ssp(target, i)            repeat while (i > 1)                set n to item i of my lst                set i to i - 1                if ((n = target) or (((n < target) or (someNegatives)) and (ssp(target - n, i)))) then return true            end repeat            return (target = beginning of my lst)        end ssp    end script    -- The search can be more efficient if it's known the list contains no negatives.    repeat with n in o's lst        if (n < 0) then            set o's someNegatives to true            exit repeat        end if    end repeat     return o's ssp(target, count o's lst)end subsetOf:sumsTo: -- Is n a Zumkeller number?on isZumkeller(n)    -- Yes if its aliquot sum is greater than or equal to it, the difference between them is even, and    -- either n is odd or a subset of its proper divisors sums to half the sum of the divisors and it.    -- Using aliquotSum() to get the divisor sum and then calling properDivisors() too if a list's actually    -- needed is generally faster than using properDivisors() in the first place and summing the result.    set sum to aliquotSum(n)    return ((sum ≥ n) and ((sum - n) mod 2 = 0) and ¬        ((n mod 2 = 1) or (my subsetOf:(properDivisors(n)) sumsTo:((sum + n) div 2))))end isZumkeller -- Task code:-- Find and return q Zumkeller numbers, starting the search at n and continuing at the-- given interval, applying the Zumkeller test only to numbers passing the given filter.on zumkellerNumbers(q, n, interval, filter)    script o        property zumkellers : {}    end script     set counter to 0    repeat until (counter = q)        if ((filter's OK(n)) and (isZumkeller(n))) then            set end of o's zumkellers to n            set counter to counter + 1        end if        set n to n + interval    end repeat     return o's zumkellersend zumkellerNumbers on joinText(textList, delimiter)    set astid to AppleScript's text item delimiters    set AppleScript's text item delimiters to delimiter    set txt to textList as text    set AppleScript's text item delimiters to astid     return txtend joinText on formatForDisplay(resultList, heading, resultsPerLine, separator)    script o        property input : resultList        property output : {heading}    end script     set len to (count o's input)    repeat with i from 1 to len by resultsPerLine        set j to i + resultsPerLine - 1        if (j > len) then set j to len        set end of o's output to joinText(items i thru j of o's input, separator)    end repeat     return joinText(o's output, linefeed)end formatForDisplay on doTask(cheating)    set output to {}    script noFilter        on OK(n)            return true        end OK    end script    set header to "1st 220 Zumkeller numbers:"    set end of output to formatForDisplay(zumkellerNumbers(220, 1, 1, noFilter), header, 20, "  ")    set header to "1st 40 odd Zumkeller numbers:"    set end of output to formatForDisplay(zumkellerNumbers(40, 1, 2, noFilter), header, 10, "  ")     -- Stretch goal:    set header to "1st 40 odd Zumkeller numbers not ending with 5:"    script no5Multiples        on OK(n)            return (n mod 5 > 0)        end OK    end script    if (cheating) then        -- Knowing that the HCF of the first 203 odd Zumkellers not ending with 5        -- is 63, just check 63 and each 126th number thereafter.        -- For the 204th - 907th such numbers, the HCF reduces to 21, so adjust accordingly.        -- (See Horsth's comments on the Talk page.)        set zumkellers to zumkellerNumbers(40, 63, 126, no5Multiples)    else        -- Otherwise check alternate numbers from 1.        set zumkellers to zumkellerNumbers(40, 1, 2, no5Multiples)    end if    set end of output to formatForDisplay(zumkellers, header, 10, "  ")     return joinText(output, linefeed & linefeed)end doTask local cheatingset cheating to falsedoTask(cheating)`
Output:
`"1st 220 Zumkeller numbers:6  12  20  24  28  30  40  42  48  54  56  60  66  70  78  80  84  88  90  96102  104  108  112  114  120  126  132  138  140  150  156  160  168  174  176  180  186  192  198204  208  210  216  220  222  224  228  234  240  246  252  258  260  264  270  272  276  280  282294  300  304  306  308  312  318  320  330  336  340  342  348  350  352  354  360  364  366  368372  378  380  384  390  396  402  408  414  416  420  426  432  438  440  444  448  456  460  462464  468  474  476  480  486  490  492  496  498  500  504  510  516  520  522  528  532  534  540544  546  550  552  558  560  564  570  572  580  582  588  594  600  606  608  612  616  618  620624  630  636  640  642  644  650  654  660  666  672  678  680  684  690  696  700  702  704  708714  720  726  728  732  736  740  744  750  756  760  762  768  770  780  786  792  798  804  810812  816  820  822  828  832  834  836  840  852  858  860  864  868  870  876  880  888  894  896906  910  912  918  920  924  928  930  936  940  942  945  948  952  960  966  972  978  980  984 1st 40 odd Zumkeller numbers:945  1575  2205  2835  3465  4095  4725  5355  5775  59856435  6615  6825  7245  7425  7875  8085  8415  8505  89259135  9555  9765  10395  11655  12285  12705  12915  13545  1417514805  15015  15435  16065  16695  17325  17955  18585  19215  19305 1st 40 odd Zumkeller numbers not ending with 5:81081  153153  171171  189189  207207  223839  243243  261261  279279  297297351351  459459  513513  567567  621621  671517  729729  742203  783783  793611812889  837837  891891  908523  960687  999999  1024947  1054053  1072071  10737091095633  1108107  1145529  1162161  1198197  1224531  1270269  1307691  1324323  1378377"`

## ARM Assembly

Works with: as version Raspberry Pi
` /* ARM assembly Raspberry PI  *//* program zumkeller4.s   *//* new version 10/2020 */  /* REMARK 1 : this program use routines in a include file    see task Include a file language arm assembly    for the routine affichageMess conversion10    see at end of this program the instruction include *//* for constantes see task include a file in arm assembly *//************************************//* Constantes                       *//************************************/.include "../constantes.inc" .equ NBDIVISORS,             1000 /*******************************************//* Initialized data                        *//*******************************************/.dataszMessStartPgm:          .asciz "Program start \n"szMessEndPgm:            .asciz "Program normal end.\n"szMessErrorArea:         .asciz "\033[31mError : area divisors too small.\n"szMessError:             .asciz "\033[31mError  !!!\n"szMessErrGen:            .asciz "Error end program.\n"szMessNbPrem:            .asciz "This number is prime !!!.\n"szMessResultFact:        .asciz "@ " szCarriageReturn:        .asciz "\n" /* datas message display */szMessEntete:            .asciz "The first 220 Zumkeller numbers are:\n"sNumber:                 .space 4*20,' '                         .space 12,' '     @ for end of conversionszMessListDivi:          .asciz "Divisors list : \n"szMessListDiviHeap:      .asciz "Heap 1 Divisors list : \n"szMessResult:            .ascii " "sValue:                  .space 12,' '                         .asciz "" szMessEntete1:            .asciz "The first 40 odd Zumkeller numbers are:\n"szMessEntete2:            .asciz "First 40 odd Zumkeller numbers not divisible by 5:\n"/*******************************************//* UnInitialized data                      *//*******************************************/.bss .align 4sZoneConv:               .skip 24tbZoneDecom:             .skip 8 * NBDIVISORS          // facteur 4 octets, nombre 4 /*******************************************//*  code section                           *//*******************************************/.text.global main main:                               @ program start    ldr r0,iAdrszMessStartPgm       @ display start message    bl affichageMess     ldr r0,iAdrszMessEntete         @ display result message    bl affichageMess    mov r2,#1    mov r3,#0    mov r4,#01:    mov r0,r2                       @  number    bl testZumkeller    cmp r0,#1    bne 3f    mov r0,r2    ldr r1,iAdrsNumber              @ and convert ascii string    lsl r5,r4,#2    add r1,r5    bl conversion10    add r4,r4,#1    cmp r4,#20    blt 2f    add r1,r1,#3    mov r0,#'\n'    strb r0,[r1]    mov r0,#0    strb r0,[r1,#1]    ldr r0,iAdrsNumber         @ display result message    bl affichageMess    mov r4,#02:    add r3,r3,#13:    add r2,r2,#1    cmp r3,#220    blt 1b     /* odd zumkeller numbers  */    ldr r0,iAdrszMessEntete1    bl affichageMess    mov r2,#1    mov r3,#0    mov r4,#04:    mov r0,r2                       @  number    bl testZumkeller    cmp r0,#1    bne 6f    mov r0,r2    ldr r1,iAdrsNumber              @ and convert ascii string    lsl r5,r4,#3    add r1,r5    bl conversion10    add r4,r4,#1    cmp r4,#8    blt 5f    add r1,r1,#8    mov r0,#'\n'    strb r0,[r1]    mov r0,#0    strb r0,[r1,#1]    ldr r0,iAdrsNumber              @ display result message    bl affichageMess    mov r4,#05:    add r3,r3,#16:    add r2,r2,#2    cmp r3,#40    blt 4b    /* odd zumkeller numbers not multiple5 */61:    ldr r0,iAdrszMessEntete2    bl affichageMess    mov r3,#0    mov r4,#07:    lsr r8,r2,#3                   @ divide counter by 5    add r8,r8,r2,lsr #4    add r8,r8,r8,lsr #4    add r8,r8,r8,lsr #8    add r8,r8,r8,lsr #16    add r9,r8,r8,lsl #2            @ multiply result by 5    sub r9,r2,r9    mov r6,#13    mul r9,r6,r9    lsr r9,#6    add r9,r8                      @ it is a quotient    add r9,r9,r9,lsl #2            @ multiply by 5    sub r9,r2,r9                   @ compute remainder    cmp r9,#0                      @ remainder = zero ?    beq 9f    mov r0,r2                      @  number    bl testZumkeller    cmp r0,#1    bne 9f    mov r0,r2    ldr r1,iAdrsNumber              @ and convert ascii string    lsl r5,r4,#3    add r1,r5    bl conversion10    add r4,r4,#1    cmp r4,#8    blt 8f    add r1,r1,#8    mov r0,#'\n'    strb r0,[r1]    mov r0,#0    strb r0,[r1,#1]    ldr r0,iAdrsNumber         @ display result message    bl affichageMess    mov r4,#08:    add r3,r3,#19:    add r2,r2,#2    cmp r3,#40    blt 7b     ldr r0,iAdrszMessEndPgm         @ display end message    bl affichageMess    b 100f99:                                 @ display error message     ldr r0,iAdrszMessError    bl affichageMess100:                                @ standard end of the program    mov r0, #0                      @ return code    mov r7, #EXIT                   @ request to exit program    svc 0                           @ perform system calliAdrszMessStartPgm:        .int szMessStartPgmiAdrszMessEndPgm:          .int szMessEndPgmiAdrszMessError:           .int szMessErroriAdrszCarriageReturn:      .int szCarriageReturniAdrszMessResult:          .int szMessResultiAdrsValue:                .int sValueiAdrtbZoneDecom:           .int tbZoneDecomiAdrszMessEntete:          .int szMessEnteteiAdrszMessEntete1:         .int szMessEntete1iAdrszMessEntete2:         .int szMessEntete2iAdrsNumber:               .int sNumber /******************************************************************//*     test if number is Zumkeller number                         */ /******************************************************************//* r0 contains the number  *//* r0 return 1 if Zumkeller number else return 0  */testZumkeller:    push {r1-r6,lr}              @ save  registers     mov r6,r0                    @ save number    ldr r1,iAdrtbZoneDecom    bl decompFact                @ create area of divisors    cmp r0,#1                    @ no divisors    movle r0,#0    ble 100f    tst r2,#1                    @ odd sum ?    movne r0,#0    bne 100f                     @ yes -> end    tst r1,#1                    @ number of odd divisors is odd ?    movne r0,#0    bne 100f                     @ yes -> end    lsl r5,r6,#1                 @ abondant number    cmp r5,r2    movgt r0,#0                      bgt 100f                     @ no -> end    mov r3,r0    mov r4,r2                    @ save sum    ldr r0,iAdrtbZoneDecom    mov r1,#0    mov r2,r3    bl shellSort                 @ sort table     mov r1,r3                    @ factors number    ldr r0,iAdrtbZoneDecom    lsr r2,r4,#1                 @ sum / 2    bl computePartIter           @  100:    pop {r1-r6,lr}              @ restaur registers    bx lr                       @ return /******************************************************************//*     search factors to sum = entry value                         */ /******************************************************************//* r0 contains address of divisors area *//* r1 contains elements number *//* r2 contains divisors sum / 2  *//* r0 return 1 if ok 0 else */computePartIter:    push {r1-r7,fp,lr}         @ save  registers     lsl r7,r1,#3               @ compute size of temp table    sub sp,r7                  @ and reserve on stack    mov fp,sp                  @ frame pointer = stack address = begin table    mov r5,#0                  @ stack indice    sub r3,r1,#11:    ldr r4,[r0,r3,lsl #2]      @ load factor    cmp r4,r2                  @ compare value    bgt 2f    beq 90f                    @ equal -> end ok    cmp r3,#0                  @ first item ?    beq 3f    sub r3,#1                  @ push indice item in temp table    add r6,fp,r5,lsl #3    str r3,[r6]    str r2,[r6,#4]             @ push sum in temp table    add r5,#1    sub r2,r4                  @ substract divisors from sum    b 1b2:    sub r3,#1                 @ other divisors    cmp r3,#0                 @ first item ?    bge 1b3:                            @ first item    cmp r5,#0                 @ stack empty ?    moveq r0,#0               @ no sum factors equal to value     beq 100f                  @ end     sub r5,#1                 @ else pop stack    add r6,fp,r5,lsl #3       @ and restaur    ldr r3,[r6]               @ indice    ldr r2,[r6,#4]            @ and value    b 1b                      @ and loop 90:    mov r0,#1                 @ it is ok 100:    add sp,r7                 @ stack alignement    pop {r1-r7,fp,lr}         @ restaur registers    bx lr                     @ return /******************************************************************//*     factor decomposition                                               */ /******************************************************************//* r0 contains number *//* r1 contains address of divisors area *//* r0 return divisors items in table *//* r1 return the number of odd divisors  *//* r2 return the sum of divisors  */decompFact:    push {r3-r8,lr}              @ save  registers    mov r5,r1    mov r8,r0                    @ save number    bl isPrime                   @ prime ?    cmp r0,#1    beq 98f                      @ yes is prime    mov r1,#1    str r1,[r5]                  @ first factor    mov r12,#1                   @ divisors sum    mov r11,#1                   @ number odd divisors    mov r4,#1                    @ indice divisors table    mov r1,#2                    @ first divisor    mov r6,#0                    @ previous divisor    mov r7,#0                    @ number of same divisors2:    mov r0,r8                    @ dividende    bl division                  @  r1 divisor r2 quotient r3 remainder    cmp r3,#0    bne 5f                       @ if remainder <> zero  -> no divisor    mov r8,r2                    @ else quotient -> new dividende    cmp r1,r6                    @ same divisor ?    beq 4f                       @ yes    mov r7,r4                    @ number factors in table    mov r9,#0                    @ indice21:    ldr r10,[r5,r9,lsl #2 ]      @ load one factor    mul r10,r1,r10               @ multiply     str r10,[r5,r7,lsl #2]       @ and store in the table    tst r10,#1                   @ divisor odd ?    addne r11,#1    add r12,r10    add r7,r7,#1                 @ and increment counter    add r9,r9,#1    cmp r9,r4      blt 21b    mov r4,r7    mov r6,r1                    @ new divisor    b 7f4:                               @ same divisor    sub r9,r4,#1    mov r7,r441:    ldr r10,[r5,r9,lsl #2 ]    cmp r10,r1    subne r9,#1    bne 41b    sub r9,r4,r942:    ldr  r10,[r5,r9,lsl #2 ]    mul r10,r1,r10    str r10,[r5,r7,lsl #2]       @ and store in the table    tst r10,#1                   @ divsor odd ?    addne r11,#1    add r12,r10    add r7,r7,#1                 @ and increment counter    add r9,r9,#1    cmp r9,r4      blt 42b    mov r4,r7    b 7f                         @ and loop     /* not divisor -> increment next divisor */5:    cmp r1,#2                    @ if divisor = 2 -> add 1     addeq r1,#1    addne r1,#2                  @ else add 2    b 2b     /* divisor -> test if new dividende is prime */7:     mov r3,r1                    @ save divisor    cmp r8,#1                    @ dividende = 1 ? -> end    beq 10f    mov r0,r8                    @ new dividende is prime ?    mov r1,#0    bl isPrime                   @ the new dividende is prime ?    cmp r0,#1    bne 10f                      @ the new dividende is not prime     cmp r8,r6                    @ else dividende is same divisor ?    beq 9f                       @ yes    mov r7,r4                    @ number factors in table    mov r9,#0                    @ indice71:    ldr r10,[r5,r9,lsl #2 ]      @ load one factor    mul r10,r8,r10               @ multiply     str r10,[r5,r7,lsl #2]       @ and store in the table    tst r10,#1                   @ divsor odd ?    addne r11,#1    add r12,r10    add r7,r7,#1                 @ and increment counter    add r9,r9,#1    cmp r9,r4      blt 71b    mov r4,r7    mov r7,#0    b 11f9:    sub r9,r4,#1    mov r7,r491:    ldr r10,[r5,r9,lsl #2 ]    cmp r10,r8    subne r9,#1    bne 91b    sub r9,r4,r992:    ldr  r10,[r5,r9,lsl #2 ]    mul r10,r8,r10    str r10,[r5,r7,lsl #2]       @ and store in the table    tst r10,#1                   @ divisor odd ?    addne r11,#1    add r12,r10    add r7,r7,#1                 @ and increment counter    add r9,r9,#1    cmp r9,r4      blt 92b    mov r4,r7    b 11f 10:    mov r1,r3                    @ current divisor = new divisor    cmp r1,r8                    @ current divisor  > new dividende ?    ble 2b                       @ no -> loop     /* end decomposition */ 11:    mov r0,r4                    @ return number of table items    mov r2,r12                   @ return sum     mov r1,r11                   @ return number of odd divisor     mov r3,#0    str r3,[r5,r4,lsl #2]        @ store zéro in last table item    b 100f  98:     //ldr r0,iAdrszMessNbPrem    //bl   affichageMess    mov r0,#1                   @ return code    b 100f99:    ldr r0,iAdrszMessError    bl   affichageMess    mov r0,#-1                  @ error code    b 100f100:    pop {r3-r8,lr}              @ restaur registers    bx lriAdrszMessNbPrem:           .int szMessNbPrem/***************************************************//*   check if a number is prime              *//***************************************************//* r0 contains the number            *//* r0 return 1 if prime  0 else */@2147483647@4294967297@131071isPrime:    push {r1-r6,lr}    @ save registers     cmp r0,#0    beq 90f    cmp r0,#17    bhi 1f    cmp r0,#3    bls 80f            @ for 1,2,3 return prime    cmp r0,#5    beq 80f            @ for 5 return prime    cmp r0,#7    beq 80f            @ for 7 return prime    cmp r0,#11    beq 80f            @ for 11 return prime    cmp r0,#13    beq 80f            @ for 13 return prime    cmp r0,#17    beq 80f            @ for 17 return prime1:    tst r0,#1          @ even ?    beq 90f            @ yes -> not prime    mov r2,r0          @ save number    sub r1,r0,#1       @ exposant n - 1    mov r0,#3          @ base    bl moduloPuR32     @ compute base power n - 1 modulo n    cmp r0,#1    bne 90f            @ if <> 1  -> not prime     mov r0,#5    bl moduloPuR32    cmp r0,#1    bne 90f     mov r0,#7    bl moduloPuR32    cmp r0,#1    bne 90f     mov r0,#11    bl moduloPuR32    cmp r0,#1    bne 90f     mov r0,#13    bl moduloPuR32    cmp r0,#1    bne 90f     mov r0,#17    bl moduloPuR32    cmp r0,#1    bne 90f80:    mov r0,#1        @ is prime    b 100f90:    mov r0,#0        @ no prime100:                 @ fin standard de la fonction     pop {r1-r6,lr}   @ restaur des registres    bx lr            @ retour de la fonction en utilisant lr /********************************************************//*   Calcul modulo de b puissance e modulo m  *//*    Exemple 4 puissance 13 modulo 497 = 445         *//*                                             *//********************************************************//* r0  nombre  *//* r1 exposant *//* r2 modulo   *//* r0 return result  */moduloPuR32:    push {r1-r7,lr}    @ save registers      cmp r0,#0          @ verif <> zero     beq 100f    cmp r2,#0          @ verif <> zero     beq 100f           @ TODO: vérifier les cas d erreur1:    mov r4,r2          @ save modulo    mov r5,r1          @ save exposant     mov r6,r0          @ save base    mov r3,#1          @ start result     mov r1,#0          @ division de r0,r1 par r2    bl division32R    mov r6,r2          @ base <- remainder2:    tst r5,#1          @  exposant even or odd    beq 3f    umull r0,r1,r6,r3    mov r2,r4    bl division32R    mov r3,r2          @ result <- remainder3:    umull r0,r1,r6,r6    mov r2,r4    bl division32R    mov r6,r2          @ base <- remainder     lsr r5,#1          @ left shift 1 bit    cmp r5,#0          @ end ?    bne 2b    mov r0,r3100:                   @ fin standard de la fonction    pop {r1-r7,lr}     @ restaur des registres    bx lr              @ retour de la fonction en utilisant lr     /***************************************************//*   division number 64 bits in 2 registers by number 32 bits *//***************************************************//* r0 contains lower part dividende   *//* r1 contains upper part dividende   *//* r2 contains divisor   *//* r0 return lower part quotient    *//* r1 return upper part quotient    *//* r2 return remainder               */division32R:    push {r3-r9,lr}    @ save registers    mov r6,#0          @ init upper upper part remainder  !!    mov r7,r1          @ init upper part remainder with upper part dividende    mov r8,r0          @ init lower part remainder with lower part dividende    mov r9,#0          @ upper part quotient     mov r4,#0          @ lower part quotient    mov r5,#32         @ bits number1:                     @ begin loop    lsl r6,#1          @ shift upper upper part remainder    lsls r7,#1         @ shift upper  part remainder    orrcs r6,#1            lsls r8,#1         @ shift lower  part remainder    orrcs r7,#1    lsls r4,#1         @ shift lower part quotient    lsl r9,#1          @ shift upper part quotient    orrcs r9,#1                       @ divisor sustract  upper  part remainder    subs r7,r2    sbcs  r6,#0        @ and substract carry    bmi 2f             @ négative ?                        @ positive or equal    orr r4,#1          @ 1 -> right bit quotient    b 3f2:                     @ negative     orr r4,#0          @ 0 -> right bit quotient    adds r7,r2         @ and restaur remainder    adc  r6,#0 3:    subs r5,#1         @ decrement bit size     bgt 1b             @ end ?    mov r0,r4          @ lower part quotient    mov r1,r9          @ upper part quotient    mov r2,r7          @ remainder100:                   @ function end    pop {r3-r9,lr}     @ restaur registers    bx lr  /***************************************************//*   shell Sort                                    *//***************************************************/ /* r0 contains the address of table *//* r1 contains the first element but not use !!   *//*   this routine use first element at index zero !!!  *//* r2 contains the number of element */shellSort:    push {r0-r7,lr}              @save registers    sub r2,#1                    @ index last item    mov r1,r2                    @ init gap = last item1:                               @ start loop 1    lsrs r1,#1                   @ gap = gap / 2    beq 100f                     @ if gap = 0 -> end    mov r3,r1                    @ init loop indice 1 2:                               @ start loop 2    ldr r4,[r0,r3,lsl #2]        @ load first value    mov r5,r3                    @ init loop indice 23:                               @ start loop 3    cmp r5,r1                    @ indice < gap    blt 4f                       @ yes -> end loop 2    sub r6,r5,r1                 @ index = indice - gap    ldr r7,[r0,r6,lsl #2]        @ load second value    cmp r4,r7                    @ compare values    strlt r7,[r0,r5,lsl #2]      @ store if <    sublt r5,r1                  @ indice = indice - gap    blt 3b                       @ and loop4:                               @ end loop 3    str r4,[r0,r5,lsl #2]        @ store value 1 at indice 2    add r3,#1                    @ increment indice 1    cmp r3,r2                    @ end ?    ble 2b                       @ no -> loop 2    b 1b                         @ yes loop for new gap 100:                             @ end function    pop {r0-r7,lr}               @ restaur registers    bx lr                        @ return /******************************************************************//*     display divisors function                         */ /******************************************************************//* r0 contains address of divisors area *//* r1 contains the number of area items  */displayDivisors:    push {r2-r8,lr}            @ save  registers     cmp r1,#0    beq 100f    mov r2,r1    mov r3,#0                   @ indice    mov r4,r01:    add r5,r4,r3,lsl #2    ldr r0,[r5]                 @ load factor     ldr r1,iAdrsZoneConv    bl conversion10             @ call décimal conversion    ldr r0,iAdrszMessResultFact    ldr r1,iAdrsZoneConv        @ insert conversion in message    bl strInsertAtCharInc    bl affichageMess            @ display message    add r3,#1                   @ other ithem    cmp r3,r2                   @ items maxi ?    blt 1b    ldr r0,iAdrszCarriageReturn    bl affichageMess     b 100f 100:    pop {r2-r8,lr}             @ restaur registers    bx lr                       @ returniAdrszMessResultFact:    .int szMessResultFactiAdrsZoneConv:           .int sZoneConv/***************************************************//*      ROUTINES INCLUDE                 *//***************************************************/.include "../affichage.inc" `
```Program start
The first 220 Zumkeller numbers are:
6   12  20  24  28  30  40  42  48  54  56  60  66  70  78  80  84  88  90  96
102 104 108 112 114 120 126 132 138 140 150 156 160 168 174 176 180 186 192 198
204 208 210 216 220 222 224 228 234 240 246 252 258 260 264 270 272 276 280 282
294 300 304 306 308 312 318 320 330 336 340 342 348 350 352 354 360 364 366 368
372 378 380 384 390 396 402 408 414 416 420 426 432 438 440 444 448 456 460 462
464 468 474 476 480 486 490 492 496 498 500 504 510 516 520 522 528 532 534 540
544 546 550 552 558 560 564 570 572 580 582 588 594 600 606 608 612 616 618 620
624 630 636 640 642 644 650 654 660 666 672 678 680 684 690 696 700 702 704 708
714 720 726 728 732 736 740 744 750 756 760 762 768 770 780 786 792 798 804 810
812 816 820 822 828 832 834 836 840 852 858 860 864 868 870 876 880 888 894 896
906 910 912 918 920 924 928 930 936 940 942 945 948 952 960 966 972 978 980 984
The first 40 odd Zumkeller numbers are:
945     1575    2205    2835    3465    4095    4725    5355
5775    5985    6435    6615    6825    7245    7425    7875
8085    8415    8505    8925    9135    9555    9765    10395
11655   12285   12705   12915   13545   14175   14805   15015
15435   16065   16695   17325   17955   18585   19215   19305
First 40 odd Zumkeller numbers not divisible by 5:
81081   153153  171171  189189  207207  223839  243243  261261
279279  297297  351351  459459  513513  567567  621621  671517
729729  742203  783783  793611  812889  837837  891891  908523
960687  999999  1024947 1054053 1072071 1073709 1095633 1108107
1145529 1162161 1198197 1224531 1270269 1307691 1324323 1378377
Program normal end.

```

## C#

Translation of: Go
`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 is odd can't be split into two partitions with equal sums            if (sum % 2 == 1) {                return false;            }            // if n is odd use 'abundant odd number' optimization            if (n % 2 == 1) {                var abundance = sum - 2 * n;                return abundance > 0 && abundance % 2 == 0;            }            // if n and sum are both even check if there's a partition which totals sum / 2            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();                    }                }            }        }    }}`
Output:
```The first 220 Zumkeller numbers are:
6  12  20  24  28  30  40  42  48  54  56  60  66  70  78  80  84  88  90  96
102 104 108 112 114 120 126 132 138 140 150 156 160 168 174 176 180 186 192 198
204 208 210 216 220 222 224 228 234 240 246 252 258 260 264 270 272 276 280 282
294 300 304 306 308 312 318 320 330 336 340 342 348 350 352 354 360 364 366 368
372 378 380 384 390 396 402 408 414 416 420 426 432 438 440 444 448 456 460 462
464 468 474 476 480 486 490 492 496 498 500 504 510 516 520 522 528 532 534 540
544 546 550 552 558 560 564 570 572 580 582 588 594 600 606 608 612 616 618 620
624 630 636 640 642 644 650 654 660 666 672 678 680 684 690 696 700 702 704 708
714 720 726 728 732 736 740 744 750 756 760 762 768 770 780 786 792 798 804 810
812 816 820 822 828 832 834 836 840 852 858 860 864 868 870 876 880 888 894 896
906 910 912 918 920 924 928 930 936 940 942 945 948 952 960 966 972 978 980 984

The first 40 odd Zumkeller numbers are:
945  1575  2205  2835  3465  4095  4725  5355  5775  5985
6435  6615  6825  7245  7425  7875  8085  8415  8505  8925
9135  9555  9765 10395 11655 12285 12705 12915 13545 14175
14805 15015 15435 16065 16695 17325 17955 18585 19215 19305

The first 40 odd Zumkeller numbers which don't end in 5 are:
81081  153153  171171  189189  207207  223839  243243  261261
279279  297297  351351  459459  513513  567567  621621  671517
729729  742203  783783  793611  812889  837837  891891  908523
960687  999999 1024947 1054053 1072071 1073709 1095633 1108107
1145529 1162161 1198197 1224531 1270269 1307691 1324323 1378377```

## C++

`#include <iostream>#include <cmath>#include <vector>#include <algorithm>#include <iomanip>#include <numeric> using namespace std; // Returns n in binary right justified with length passed and padded with zeroesconst uint* binary(uint n, uint length); // Returns the sum of the binary ordered subset of rank r.// Adapted from Sympy implementation.uint sum_subset_unrank_bin(const vector<uint>& d, uint r); vector<uint> factors(uint x); bool isPrime(uint number); bool isZum(uint n); ostream& operator<<(ostream& os, const vector<uint>& zumz) {    for (uint i = 0; i < zumz.size(); i++) {        if (i % 10 == 0)            os << endl;        os << setw(10) << zumz[i] << ' ';    }    return os;} int main() {    cout << "First 220 Zumkeller numbers:" << endl;    vector<uint> zumz;    for (uint n = 2; zumz.size() < 220; n++)        if (isZum(n))            zumz.push_back(n);    cout << zumz << endl << endl;     cout << "First 40 odd Zumkeller numbers:" << endl;    vector<uint> zumz2;    for (uint n = 2; zumz2.size() < 40; n++)        if (n % 2 && isZum(n))            zumz2.push_back(n);    cout << zumz2 << endl << endl;     cout << "First 40 odd Zumkeller numbers not ending in 5:" << endl;    vector<uint> zumz3;    for (uint n = 2; zumz3.size() < 40; n++)        if (n % 2 && (n % 10) !=  5 && isZum(n))            zumz3.push_back(n);    cout << zumz3 << endl << endl;     return 0;} // Returns n in binary right justified with length passed and padded with zeroesconst uint* binary(uint n, uint length) {    uint* bin = new uint[length];	    // array to hold result    fill(bin, bin + length, 0);         // fill with zeroes    // convert n to binary and store right justified in bin    for (uint i = 0; n > 0; i++) {        uint rem = n % 2;        n /= 2;        if (rem)            bin[length - 1 - i] = 1;    }     return bin;} // Returns the sum of the binary ordered subset of rank r.// Adapted from Sympy implementation.uint sum_subset_unrank_bin(const vector<uint>& d, uint r) {    vector<uint> subset;    // convert r to binary array of same size as d    const uint* bits = binary(r, d.size() - 1);     // get binary ordered subset    for (uint i = 0; i < d.size() - 1; i++)        if (bits[i])            subset.push_back(d[i]);     delete[] bits;     return accumulate(subset.begin(), subset.end(), 0u);} vector<uint> factors(uint x) {    vector<uint> result;    // this will loop from 1 to int(sqrt(x))    for (uint i = 1; i * i <= x; i++) {        // Check if i divides x without leaving a remainder        if (x % i == 0) {            result.push_back(i);             if (x / i != i)                result.push_back(x / i);        }    }     // return the sorted factors of x    sort(result.begin(), result.end());    return result;} bool isPrime(uint number) {    if (number < 2) return false;    if (number == 2) return true;    if (number % 2 == 0) return false;    for (uint i = 3; i * i <= number; i += 2)        if (number % i == 0) return false;     return true;} bool isZum(uint n) {    // if prime it ain't no zum    if (isPrime(n))        return false;     // get sum of divisors    const auto d = factors(n);    uint s = accumulate(d.begin(), d.end(), 0u);     // if sum is odd or sum < 2*n it ain't no zum    if (s % 2 || s < 2 * n)        return false;     // if we get here and n is odd or n has at least 24 divisors it's a zum!    // Valid for even n < 99504. To test n beyond this bound, comment out this condition.    // And wait all day. Thanks to User:Horsth for taking the time to find this bound!    if (n % 2 || d.size() >= 24)        return true;     if (!(s % 2) && d[d.size() - 1] <= s / 2)        for (uint x = 2; (uint) log2(x) < (d.size() - 1); x++) // using log2 prevents overflow            if (sum_subset_unrank_bin(d, x) == s / 2)                return true; // congratulations it's a zum num!!     // if we get here it ain't no zum    return false;}`
Output:
```First 220 Zumkeller numbers:

6         12         20         24         28         30         40         42         48         54
56         60         66         70         78         80         84         88         90         96
102        104        108        112        114        120        126        132        138        140
150        156        160        168        174        176        180        186        192        198
204        208        210        216        220        222        224        228        234        240
246        252        258        260        264        270        272        276        280        282
294        300        304        306        308        312        318        320        330        336
340        342        348        350        352        354        360        364        366        368
372        378        380        384        390        396        402        408        414        416
420        426        432        438        440        444        448        456        460        462
464        468        474        476        480        486        490        492        496        498
500        504        510        516        520        522        528        532        534        540
544        546        550        552        558        560        564        570        572        580
582        588        594        600        606        608        612        616        618        620
624        630        636        640        642        644        650        654        660        666
672        678        680        684        690        696        700        702        704        708
714        720        726        728        732        736        740        744        750        756
760        762        768        770        780        786        792        798        804        810
812        816        820        822        828        832        834        836        840        852
858        860        864        868        870        876        880        888        894        896
906        910        912        918        920        924        928        930        936        940
942        945        948        952        960        966        972        978        980        984

First 40 odd Zumkeller numbers:

945       1575       2205       2835       3465       4095       4725       5355       5775       5985
6435       6615       6825       7245       7425       7875       8085       8415       8505       8925
9135       9555       9765      10395      11655      12285      12705      12915      13545      14175
14805      15015      15435      16065      16695      17325      17955      18585      19215      19305

First 40 odd Zumkeller numbers not ending in 5:

81081     153153     171171     189189     207207     223839     243243     261261     279279     297297
351351     459459     513513     567567     621621     671517     729729     742203     783783     793611
812889     837837     891891     908523     960687     999999    1024947    1054053    1072071    1073709
1095633    1108107    1145529    1162161    1198197    1224531    1270269    1307691    1324323    1378377
```

## D

Translation of: C#
`import std.algorithm;import std.stdio; int[] getDivisors(int n) {    auto divs = [1, n];    for (int i = 2; i * i <= n; i++) {        if (n % i == 0) {            divs ~= i;             int j = n / i;            if (i != j) {                divs ~= j;            }        }    }    return divs;} bool isPartSum(int[] divs, int sum) {    if (sum == 0) {        return true;    }    auto le = divs.length;    if (le == 0) {        return false;    }    auto last = divs[\$ - 1];    int[] newDivs;    for (int i = 0; i < le - 1; i++) {        newDivs ~= divs[i];    }    if (last > sum) {        return isPartSum(newDivs, sum);    } else {        return isPartSum(newDivs, sum) || isPartSum(newDivs, sum - last);    }} bool isZumkeller(int n) {    auto divs = getDivisors(n);    auto sum = divs.sum();    // if sum is odd can't be split into two partitions with equal sums    if (sum % 2 == 1) {        return false;    }    // if n is odd use 'abundant odd number' optimization    if (n % 2 == 1) {        auto abundance = sum - 2 * n;        return abundance > 0 && abundance % 2 == 0;    }    // if n and sum are both even check if there's a partition which totals sum / 2    return isPartSum(divs, sum / 2);} void main() {    writeln("The first 220 Zumkeller numbers are:");    int i = 2;    for (int count = 0; count < 220; i++) {        if (isZumkeller(i)) {            writef("%3d ", i);            count++;            if (count % 20 == 0) {                writeln;            }        }    }     writeln("\nThe first 40 odd Zumkeller numbers are:");    i = 3;    for (int count = 0; count < 40; i += 2) {        if (isZumkeller(i)) {            writef("%5d ", i);            count++;            if (count % 10 == 0) {                writeln;            }        }    }     writeln("\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)) {            writef("%7d ", i);            count++;            if (count % 8 == 0) {                writeln;            }        }    }}`
Output:
```The first 220 Zumkeller numbers are:
6  12  20  24  28  30  40  42  48  54  56  60  66  70  78  80  84  88  90  96
102 104 108 112 114 120 126 132 138 140 150 156 160 168 174 176 180 186 192 198
204 208 210 216 220 222 224 228 234 240 246 252 258 260 264 270 272 276 280 282
294 300 304 306 308 312 318 320 330 336 340 342 348 350 352 354 360 364 366 368
372 378 380 384 390 396 402 408 414 416 420 426 432 438 440 444 448 456 460 462
464 468 474 476 480 486 490 492 496 498 500 504 510 516 520 522 528 532 534 540
544 546 550 552 558 560 564 570 572 580 582 588 594 600 606 608 612 616 618 620
624 630 636 640 642 644 650 654 660 666 672 678 680 684 690 696 700 702 704 708
714 720 726 728 732 736 740 744 750 756 760 762 768 770 780 786 792 798 804 810
812 816 820 822 828 832 834 836 840 852 858 860 864 868 870 876 880 888 894 896
906 910 912 918 920 924 928 930 936 940 942 945 948 952 960 966 972 978 980 984

The first 40 odd Zumkeller numbers are:
945  1575  2205  2835  3465  4095  4725  5355  5775  5985
6435  6615  6825  7245  7425  7875  8085  8415  8505  8925
9135  9555  9765 10395 11655 12285 12705 12915 13545 14175
14805 15015 15435 16065 16695 17325 17955 18585 19215 19305

The first 40 odd Zumkeller numbers which don't end in 5 are:
81081  153153  171171  189189  207207  223839  243243  261261
279279  297297  351351  459459  513513  567567  621621  671517
729729  742203  783783  793611  812889  837837  891891  908523
960687  999999 1024947 1054053 1072071 1073709 1095633 1108107
1145529 1162161 1198197 1224531 1270269 1307691 1324323 1378377```

## F#

` // Zumkeller numbers: Nigel Galloway. May 16th., 2021let rec fG n g=match g with h::_ when h>=n->h=n |h::t->fG n t || fG(n-h) t |_->falselet fN g=function n when n&&&1=1->false                 |n->let e=n/2-g in match compare e 0 with 0->true                                                          |1->let l=[1..e]|>List.filter(fun n->g%n=0)                                                              match compare(l|>List.sum) e with 1->fG e l |0->true |_->false                                                          |_->falseSeq.initInfinite((+)1)|>Seq.map(fun n->(n,sod n))|>Seq.filter(fun(n,g)->fN n g)|>Seq.take 220|>Seq.iter(fun(n,_)->printf "%d " n); printfn "\n"Seq.initInfinite((*)2>>(+)1)|>Seq.map(fun n->(n,sod n))|>Seq.filter(fun(n,g)->fN n g)|>Seq.take 40|>Seq.iter(fun(n,_)->printf "%d " n); printfn "\n"Seq.initInfinite((*)2>>(+)1)|>Seq.filter(fun n->n%10<>5)|>Seq.map(fun n->(n,sod n))|>Seq.filter(fun(n,g)->fN n g)|>Seq.take 40|>Seq.iter(fun(n,_)->printf "%d " n); printfn "\n" `
Output:
```6 12 20 24 28 30 40 42 48 54 56 60 66 70 78 80 84 88 90 96 102 104 108 112 114 120 126 132 138 140 150 156 160 168 174 176 180 186 192 198 204 208 210 216 220 222 224 228 234 240 246 252 258 260 264 270 272 276 280 282 294 300 304 306 308 312 318 320 330 336 340 342 348 350 352 354 360 364 366 368 372 378 380 384 390 396 402 408 414 416 420 426 432 438 440 444 448 456 460 462 464 468 474 476 480 486 490 492 496 498 500 504 510 516 520 522 528 532 534 540 544 546 550 552 558 560 564 570 572 580 582 588 594 600 606 608 612 616 618 620 624 630 636 640 642 644 650 654 660 666 672 678 680 684 690 696 700 702 704 708 714 720 726 728 732 736 740 744 750 756 760 762 768 770 780 786 792 798 804 810 812 816 820 822 828 832 834 836 840 852 858 860 864 868 870 876 880 888 894 896 906 910 912 918 920 924 928 930 936 940 942 945 948 952 960 966 972 978 980 984

945 1575 2205 2835 3465 4095 4725 5355 5775 5985 6435 6615 6825 7245 7425 7875 8085 8415 8505 8925 9135 9555 9765 10395 11655 12285 12705 12915 13545 14175 14805 15015 15435 16065 16695 17325 17955 18585 19215 19305

81081 153153 171171 189189 207207 223839 243243 261261 279279 297297 351351 459459 513513 567567 621621 671517 729729 742203 783783 793611 812889 837837 891891 908523 960687 999999 1024947 1054053 1072071 1073709 1095633 1108107 1145529 1162161 1198197 1224531 1270269 1307691 1324323 1378377
```

## Factor

Works with: Factor version 0.99 2019-10-06
`USING: combinators grouping io kernel lists lists.lazy mathmath.primes.factors memoize prettyprint sequences ; MEMO: psum? ( seq n -- ? )    {        { [ dup zero? ] [ 2drop t ] }        { [ over length zero? ] [ 2drop f ] }        { [ over last over > ] [ [ but-last ] dip psum? ] }        [            [ [ but-last ] dip psum? ]            [ over last - [ but-last ] dip psum? ] 2bi or        ]    } cond ; : zumkeller? ( n -- ? )    dup divisors dup sum    {        { [ dup odd? ] [ 3drop f ] }        { [ pick odd? ] [ nip swap 2 * - [ 0 > ] [ even? ] bi and ] }        [ nipd 2/ psum? ]    } cond ; : zumkellers ( -- list )    1 lfrom [ zumkeller? ] lfilter ; : odd-zumkellers ( -- list )    1 [ 2 + ] lfrom-by [ zumkeller? ] lfilter ; : odd-zumkellers-no-5 ( -- list )    odd-zumkellers [ 5 mod zero? not ] lfilter ; : show ( count list row-len -- )    [ ltake list>array ] dip group simple-table. nl ; "First 220 Zumkeller numbers:" print220 zumkellers 20 show "First 40 odd Zumkeller numbers:" print40 odd-zumkellers 10 show "First 40 odd Zumkeller numbers not ending with 5:" print40 odd-zumkellers-no-5 8 show`
Output:
```First 220 Zumkeller numbers:
6   12  20  24  28  30  40  42  48  54  56  60  66  70  78  80  84  88  90  96
102 104 108 112 114 120 126 132 138 140 150 156 160 168 174 176 180 186 192 198
204 208 210 216 220 222 224 228 234 240 246 252 258 260 264 270 272 276 280 282
294 300 304 306 308 312 318 320 330 336 340 342 348 350 352 354 360 364 366 368
372 378 380 384 390 396 402 408 414 416 420 426 432 438 440 444 448 456 460 462
464 468 474 476 480 486 490 492 496 498 500 504 510 516 520 522 528 532 534 540
544 546 550 552 558 560 564 570 572 580 582 588 594 600 606 608 612 616 618 620
624 630 636 640 642 644 650 654 660 666 672 678 680 684 690 696 700 702 704 708
714 720 726 728 732 736 740 744 750 756 760 762 768 770 780 786 792 798 804 810
812 816 820 822 828 832 834 836 840 852 858 860 864 868 870 876 880 888 894 896
906 910 912 918 920 924 928 930 936 940 942 945 948 952 960 966 972 978 980 984

First 40 odd Zumkeller numbers:
945   1575  2205  2835  3465  4095  4725  5355  5775  5985
6435  6615  6825  7245  7425  7875  8085  8415  8505  8925
9135  9555  9765  10395 11655 12285 12705 12915 13545 14175
14805 15015 15435 16065 16695 17325 17955 18585 19215 19305

First 40 odd Zumkeller numbers not ending with 5:
81081   153153  171171  189189  207207  223839  243243  261261
279279  297297  351351  459459  513513  567567  621621  671517
729729  742203  783783  793611  812889  837837  891891  908523
960687  999999  1024947 1054053 1072071 1073709 1095633 1108107
1145529 1162161 1198197 1224531 1270269 1307691 1324323 1378377
```

## Go

`package main import "fmt" func getDivisors(n int) []int {    divs := []int{1, n}    for i := 2; i*i <= n; i++ {        if n%i == 0 {            j := n / i            divs = append(divs, i)            if i != j {                divs = append(divs, j)            }        }    }    return divs} func sum(divs []int) int {    sum := 0    for _, div := range divs {        sum += div    }    return sum} func isPartSum(divs []int, sum int) bool {    if sum == 0 {        return true    }    le := len(divs)    if le == 0 {        return false    }    last := divs[le-1]    divs = divs[0 : le-1]    if last > sum {        return isPartSum(divs, sum)    }    return isPartSum(divs, sum) || isPartSum(divs, sum-last)} func isZumkeller(n int) bool {    divs := getDivisors(n)    sum := sum(divs)    // if sum is odd can't be split into two partitions with equal sums    if sum%2 == 1 {        return false    }    // if n is odd use 'abundant odd number' optimization    if n%2 == 1 {        abundance := sum - 2*n        return abundance > 0 && abundance%2 == 0    }    // if n and sum are both even check if there's a partition which totals sum / 2    return isPartSum(divs, sum/2)} func main() {    fmt.Println("The first 220 Zumkeller numbers are:")    for i, count := 2, 0; count < 220; i++ {        if isZumkeller(i) {            fmt.Printf("%3d ", i)            count++            if count%20 == 0 {                fmt.Println()            }        }    }    fmt.Println("\nThe first 40 odd Zumkeller numbers are:")    for i, count := 3, 0; count < 40; i += 2 {        if isZumkeller(i) {            fmt.Printf("%5d ", i)            count++            if count%10 == 0 {                fmt.Println()            }        }    }    fmt.Println("\nThe first 40 odd Zumkeller numbers which don't end in 5 are:")    for i, count := 3, 0; count < 40; i += 2 {        if (i % 10 != 5) && isZumkeller(i) {            fmt.Printf("%7d ", i)            count++            if count%8 == 0 {                fmt.Println()            }        }    }    fmt.Println()}`
Output:
```The first 220 Zumkeller numbers are:
6  12  20  24  28  30  40  42  48  54  56  60  66  70  78  80  84  88  90  96
102 104 108 112 114 120 126 132 138 140 150 156 160 168 174 176 180 186 192 198
204 208 210 216 220 222 224 228 234 240 246 252 258 260 264 270 272 276 280 282
294 300 304 306 308 312 318 320 330 336 340 342 348 350 352 354 360 364 366 368
372 378 380 384 390 396 402 408 414 416 420 426 432 438 440 444 448 456 460 462
464 468 474 476 480 486 490 492 496 498 500 504 510 516 520 522 528 532 534 540
544 546 550 552 558 560 564 570 572 580 582 588 594 600 606 608 612 616 618 620
624 630 636 640 642 644 650 654 660 666 672 678 680 684 690 696 700 702 704 708
714 720 726 728 732 736 740 744 750 756 760 762 768 770 780 786 792 798 804 810
812 816 820 822 828 832 834 836 840 852 858 860 864 868 870 876 880 888 894 896
906 910 912 918 920 924 928 930 936 940 942 945 948 952 960 966 972 978 980 984

The first 40 odd Zumkeller numbers are:
945  1575  2205  2835  3465  4095  4725  5355  5775  5985
6435  6615  6825  7245  7425  7875  8085  8415  8505  8925
9135  9555  9765 10395 11655 12285 12705 12915 13545 14175
14805 15015 15435 16065 16695 17325 17955 18585 19215 19305

The first 40 odd Zumkeller numbers which don't end in 5 are:
81081  153153  171171  189189  207207  223839  243243  261261
279279  297297  351351  459459  513513  567567  621621  671517
729729  742203  783783  793611  812889  837837  891891  908523
960687  999999 1024947 1054053 1072071 1073709 1095633 1108107
1145529 1162161 1198197 1224531 1270269 1307691 1324323 1378377
```

Translation of: Python
`import Data.List (group, sort)import Data.List.Split (chunksOf)import Data.Numbers.Primes (primeFactors) -------------------- ZUMKELLER NUMBERS ------------------- isZumkeller :: Int -> BoolisZumkeller n =  let ds = divisors n      m = sum ds   in ( even m          && let half = div m 2              in elem half ds                   || ( all (half >=) ds                          && summable half ds                      )      ) summable :: Int -> [Int] -> Boolsummable _ [] = Falsesummable x xs@(h : t) =  elem x xs    || summable (x - h) t    || summable x t divisors :: Int -> [Int]divisors x =  sort    ( foldr        ( flip ((<*>) . fmap (*))            . scanl (*) 1        )        [1]        (group (primeFactors x))    ) --------------------------- TEST -------------------------main :: IO ()main =  mapM_    ( \(s, n, xs) ->        putStrLn \$          s            <> ( '\n' :                 tabulated                   10                   (take n (filter isZumkeller xs))               )    )    [ ("First 220 Zumkeller numbers:", 220, [1 ..]),      ("First 40 odd Zumkeller numbers:", 40, [1, 3 ..])    ] ------------------------- DISPLAY ------------------------tabulated ::  Show a =>  Int ->  [a] ->  Stringtabulated nCols = go  where    go xs =      let ts = show <\$> xs          w = succ (maximum (length <\$> ts))       in unlines            ( concat                <\$> chunksOf                  nCols                  (justifyRight w ' ' <\$> ts)            ) justifyRight :: Int -> Char -> String -> StringjustifyRight n c = (drop . length) <*> (replicate n c <>)`
Output:
```First 220 Zumkeller numbers:
6  12  20  24  28  30  40  42  48  54
56  60  66  70  78  80  84  88  90  96
102 104 108 112 114 120 126 132 138 140
150 156 160 168 174 176 180 186 192 198
204 208 210 216 220 222 224 228 234 240
246 252 258 260 264 270 272 276 280 282
294 300 304 306 308 312 318 320 330 336
340 342 348 350 352 354 360 364 366 368
372 378 380 384 390 396 402 408 414 416
420 426 432 438 440 444 448 456 460 462
464 468 474 476 480 486 490 492 496 498
500 504 510 516 520 522 528 532 534 540
544 546 550 552 558 560 564 570 572 580
582 588 594 600 606 608 612 616 618 620
624 630 636 640 642 644 650 654 660 666
672 678 680 684 690 696 700 702 704 708
714 720 726 728 732 736 740 744 750 756
760 762 768 770 780 786 792 798 804 810
812 816 820 822 828 832 834 836 840 852
858 860 864 868 870 876 880 888 894 896
906 910 912 918 920 924 928 930 936 940
942 945 948 952 960 966 972 978 980 984

First 40 odd Zumkeller numbers:
945  1575  2205  2835  3465  4095  4725  5355  5775  5985
6435  6615  6825  7245  7425  7875  8085  8415  8505  8925
9135  9555  9765 10395 11655 12285 12705 12915 13545 14175
14805 15015 15435 16065 16695 17325 17955 18585 19215 19305```

## Java

` import java.util.ArrayList;import java.util.Collections;import java.util.List; public class ZumkellerNumbers {     public static void main(String[] args) {        int n = 1;        System.out.printf("First 220 Zumkeller numbers:%n");        for ( int count = 1 ; count <= 220 ; n += 1 ) {            if ( isZumkeller(n) ) {                System.out.printf("%3d  ", n);                if ( count % 20 == 0 ) {                    System.out.printf("%n");                }                count++;            }        }         n = 1;        System.out.printf("%nFirst 40 odd Zumkeller numbers:%n");        for ( int count = 1 ; count <= 40 ; n += 2 ) {            if ( isZumkeller(n) ) {                System.out.printf("%6d", n);                if ( count % 10 == 0 ) {                    System.out.printf("%n");                }                count++;            }        }         n = 1;        System.out.printf("%nFirst 40 odd Zumkeller numbers that do not end in a 5:%n");        for ( int count = 1 ; count <= 40 ; n += 2 ) {            if ( n % 5 != 0 && isZumkeller(n) ) {                System.out.printf("%8d", n);                if ( count % 10 == 0 ) {                    System.out.printf("%n");                }                count++;            }        }     }     private static boolean isZumkeller(int n) {        //  numbers congruent to 6 or 12 modulo 18 are Zumkeller numbers        if ( n % 18 == 6 || n % 18 == 12 ) {            return true;        }         List<Integer> divisors = getDivisors(n);                int divisorSum = divisors.stream().mapToInt(i -> i.intValue()).sum();         //  divisor sum cannot be odd        if ( divisorSum % 2 == 1 ) {            return false;        }         // numbers where n is odd and the abundance is even are Zumkeller numbers        int abundance = divisorSum - 2 * n;        if ( n % 2 == 1 && abundance > 0 && abundance % 2 == 0 ) {            return true;        }         Collections.sort(divisors);        int j = divisors.size() - 1;        int sum = divisorSum/2;         //  Largest divisor larger than sum - then cannot partition and not Zumkeller number        if ( divisors.get(j) > sum ) {            return false;        }         return canPartition(j, divisors, sum, new int[2]);    }     private static boolean canPartition(int j, List<Integer> divisors, int sum, int[] buckets) {        if ( j < 0 ) {            return true;        }        for ( int i = 0 ; i < 2 ; i++ ) {            if ( buckets[i] + divisors.get(j) <= sum ) {                buckets[i] += divisors.get(j);                if ( canPartition(j-1, divisors, sum, buckets) ) {                    return true;                }                buckets[i] -= divisors.get(j);            }            if( buckets[i] == 0 ) {                break;            }        }        return false;    }     private static final List<Integer> getDivisors(int number) {        List<Integer> divisors = new ArrayList<Integer>();        long sqrt = (long) Math.sqrt(number);        for ( int i = 1 ; i <= sqrt ; i++ ) {            if ( number % i == 0 ) {                divisors.add(i);                int div = number / i;                if ( div != i ) {                    divisors.add(div);                }            }        }        return divisors;    } } `
Output:
```First 220 Zumkeller numbers:
6   12   20   24   28   30   40   42   48   54   56   60   66   70   78   80   84   88   90   96
102  104  108  112  114  120  126  132  138  140  150  156  160  168  174  176  180  186  192  198
204  208  210  216  220  222  224  228  234  240  246  252  258  260  264  270  272  276  280  282
294  300  304  306  308  312  318  320  330  336  340  342  348  350  352  354  360  364  366  368
372  378  380  384  390  396  402  408  414  416  420  426  432  438  440  444  448  456  460  462
464  468  474  476  480  486  490  492  496  498  500  504  510  516  520  522  528  532  534  540
544  546  550  552  558  560  564  570  572  580  582  588  594  600  606  608  612  616  618  620
624  630  636  640  642  644  650  654  660  666  672  678  680  684  690  696  700  702  704  708
714  720  726  728  732  736  740  744  750  756  760  762  768  770  780  786  792  798  804  810
812  816  820  822  828  832  834  836  840  852  858  860  864  868  870  876  880  888  894  896
906  910  912  918  920  924  928  930  936  940  942  945  948  952  960  966  972  978  980  984

First 40 odd Zumkeller numbers:
945  1575  2205  2835  3465  4095  4725  5355  5775  5985
6435  6615  6825  7245  7425  7875  8085  8415  8505  8925
9135  9555  9765 10395 11655 12285 12705 12915 13545 14175
14805 15015 15435 16065 16695 17325 17955 18585 19215 19305

First 40 odd Zumkeller numbers that do not end in a 5:
81081  153153  171171  189189  207207  223839  243243  261261  279279  297297
351351  459459  513513  567567  621621  671517  729729  742203  783783  793611
812889  837837  891891  908523  960687  999999 1024947 1054053 1072071 1073709
1095633 1108107 1145529 1162161 1198197 1224531 1270269 1307691 1324323 1378377
```

## jq

Works with: jq version 1.5

From a practical point of view, jq is not well-suited to these tasks, e.g. using the program shown here, the first task (computing the first 220 Zumkeller numbers) takes about 1 second.

The main point of interest here, therefore, is the partitioning function, or rather how a generic partitioning function that generates a stream of partitions is easily transformed into a specialized function that prunes irrelevant partitions efficiently.

`# The factors, sorteddef factors:  . as \$num  | reduce range(1; 1 + sqrt|floor) as \$i      ([];       if (\$num % \$i) == 0 then         (\$num / \$i) as \$r         | if \$i == \$r then . + [\$i] else . + [\$i, \$r] end       else .        end       | sort) ; # If the input is a sorted array of distinct non-negative integers,# then the output will be a stream of [\$x,\$y] arrays,# where \$x and \$y are non-empty arrays that partition the# input, and where (\$x|add) == \$sum.# If [\$x,\$y] is emitted, then [\$y,\$x] will not also be emitted.# The items in \$x appear in the same order as in the input, and similarly# for \$y.#def distinct_partitions(\$sum):  # input: [\$array, \$n, \$lim] where \$n>0  # output: a stream of arrays, \$a, each with \$n distinct items from \$array,  #         preserving the order in \$array, and such that  #         add == \$lim  def p:     . as [\$in, \$n, \$lim]     | if \$n==1  # this condition is very common so it saves time to check early on       then (\$in | bsearch(\$lim)) as \$ix       | if \$ix < 0 then empty         else [\$lim]         end       else (\$in|length) as \$length       | if \$length <= \$n then empty         elif \$length==\$n            then \$in | select(add == \$lim)         elif (\$in[-\$n:]|add) < \$lim then empty         else  (\$in[:\$n]|add) as \$rsum         | if \$rsum > \$lim      then empty            elif \$rsum == \$lim   then "amazing" | debug | \$in[:\$n]           else range(0; 1 + \$length - \$n) as \$i           | [\$in[\$i]] + ([\$in[\$i+1:], \$n-1, \$lim - \$in[\$i]]|p)           end         end       end;   range(1; (1+length)/2) as \$i  | ([., \$i, \$sum]|p) as \$pi  | [ \$pi, (. - \$pi)]  | select( if (.[0]|length) == (.[1]|length) then (.[0] < .[1]) else true end) #1  ; def zumkellerPartitions:  factors  | add as \$sum  | if \$sum % 2 == 1 then empty    else distinct_partitions(\$sum / 2)    end; def is_zumkeller:  first(factors        | add as \$sum        | if \$sum % 2 == 1 then empty          else distinct_partitions(\$sum / 2)	  | select( (.[0]|add) == (.[1]|add)) // ("internal error: \(.)" | debug | empty)  #2	  end	| true)  // false;`
`## The tasks: "First 220:", limit(220; range(2; infinite) | select(is_zumkeller)),"""First 40 odd:", limit(40; range(3; infinite; 2) | select(is_zumkeller))`
Output:
```First 220:
6
12
20
24
28
...
984

First 40 odd:
945
1575
2205
2835
3465
...
19305```

## Julia

`using Primes function factorize(n)    f = [one(n)]    for (p, x) in factor(n)        f = reduce(vcat, [f*p^i for i in 1:x], init=f)    end    fend function cansum(goal, list)    if goal == 0 || list[1] == goal         return true    elseif length(list) > 1        if list[1] > goal            return cansum(goal, list[2:end])        else            return cansum(goal - list[1], list[2:end]) ||  cansum(goal, list[2:end])        end    end    return falseend function iszumkeller(n)    f = reverse(factorize(n))    fsum = sum(f)    return iseven(fsum) && cansum(div(fsum, 2) - f[1], f[2:end])end function printconditionalnum(condition, maxcount, numperline = 20)    count, spacing = 1, div(80, numperline)    for i in 1:typemax(Int)        if condition(i)            count += 1            print(rpad(i, spacing), (count - 1) % numperline == 0 ? "\n" : "")            if count > maxcount                return            end        end    endend println("First 220 Zumkeller numbers:")printconditionalnum(iszumkeller, 220)println("\n\nFirst 40 odd Zumkeller numbers:")printconditionalnum((n) -> isodd(n) && iszumkeller(n), 40, 8)println("\n\nFirst 40 odd Zumkeller numbers not ending with 5:")printconditionalnum((n) -> isodd(n) && (string(n)[end] != '5') && iszumkeller(n), 40, 8) `
Output:
```First 220 Zumkeller numbers:
6   12  20  24  28  30  40  42  48  54  56  60  66  70  78  80  84  88  90  96
102 104 108 112 114 120 126 132 138 140 150 156 160 168 174 176 180 186 192 198
204 208 210 216 220 222 224 228 234 240 246 252 258 260 264 270 272 276 280 282
294 300 304 306 308 312 318 320 330 336 340 342 348 350 352 354 360 364 366 368
372 378 380 384 390 396 402 408 414 416 420 426 432 438 440 444 448 456 460 462
464 468 474 476 480 486 490 492 496 498 500 504 510 516 520 522 528 532 534 540
544 546 550 552 558 560 564 570 572 580 582 588 594 600 606 608 612 616 618 620
624 630 636 640 642 644 650 654 660 666 672 678 680 684 690 696 700 702 704 708
714 720 726 728 732 736 740 744 750 756 760 762 768 770 780 786 792 798 804 810
812 816 820 822 828 832 834 836 840 852 858 860 864 868 870 876 880 888 894 896
906 910 912 918 920 924 928 930 936 940 942 945 948 952 960 966 972 978 980 984

First 40 odd Zumkeller numbers:
945       1575      2205      2835      3465      4095      4725      5355
5775      5985      6435      6615      6825      7245      7425      7875
8085      8415      8505      8925      9135      9555      9765      10395
11655     12285     12705     12915     13545     14175     14805     15015
15435     16065     16695     17325     17955     18585     19215     19305

First 40 odd Zumkeller numbers not ending with 5:
81081     153153    171171    189189    207207    223839    243243    261261
279279    297297    351351    459459    513513    567567    621621    671517
729729    742203    783783    793611    812889    837837    891891    908523
960687    999999    1024947   1054053   1072071   1073709   1095633   1108107
1145529   1162161   1198197   1224531   1270269   1307691   1324323   1378377
```

## Kotlin

Translation of: Java
`import java.util.ArrayListimport kotlin.math.sqrt object ZumkellerNumbers {    @JvmStatic    fun main(args: Array<String>) {        var n = 1        println("First 220 Zumkeller numbers:")        run {            var count = 1            while (count <= 220) {                if (isZumkeller(n)) {                    print("%3d  ".format(n))                    if (count % 20 == 0) {                        println()                    }                    count++                }                n += 1            }        }         n = 1        println("\nFirst 40 odd Zumkeller numbers:")        run {            var count = 1            while (count <= 40) {                if (isZumkeller(n)) {                    print("%6d".format(n))                    if (count % 10 == 0) {                        println()                    }                    count++                }                n += 2            }        }         n = 1        println("\nFirst 40 odd Zumkeller numbers that do not end in a 5:")        var count = 1        while (count <= 40) {            if (n % 5 != 0 && isZumkeller(n)) {                print("%8d".format(n))                if (count % 10 == 0) {                    println()                }                count++            }            n += 2        }    }     private fun isZumkeller(n: Int): Boolean { //  numbers congruent to 6 or 12 modulo 18 are Zumkeller numbers        if (n % 18 == 6 || n % 18 == 12) {            return true        }        val divisors = getDivisors(n)        val divisorSum = divisors.stream().mapToInt { i: Int? -> i!! }.sum()        //  divisor sum cannot be odd        if (divisorSum % 2 == 1) {            return false        }        // numbers where n is odd and the abundance is even are Zumkeller numbers        val abundance = divisorSum - 2 * n        if (n % 2 == 1 && abundance > 0 && abundance % 2 == 0) {            return true        }        divisors.sort()        val j = divisors.size - 1        val sum = divisorSum / 2        //  Largest divisor larger than sum - then cannot partition and not Zumkeller number        return if (divisors[j] > sum) false else canPartition(j, divisors, sum, IntArray(2))    }     private fun canPartition(j: Int, divisors: List<Int>, sum: Int, buckets: IntArray): Boolean {        if (j < 0) {            return true        }        for (i in 0..1) {            if (buckets[i] + divisors[j] <= sum) {                buckets[i] += divisors[j]                if (canPartition(j - 1, divisors, sum, buckets)) {                    return true                }                buckets[i] -= divisors[j]            }            if (buckets[i] == 0) {                break            }        }        return false    }     private fun getDivisors(number: Int): MutableList<Int> {        val divisors: MutableList<Int> = ArrayList()        val sqrt = sqrt(number.toDouble()).toLong()        for (i in 1..sqrt) {            if (number % i == 0L) {                divisors.add(i.toInt())                val div = (number / i).toInt()                if (div.toLong() != i) {                    divisors.add(div)                }            }        }        return divisors    }}`
Output:
```First 220 Zumkeller numbers:
6   12   20   24   28   30   40   42   48   54   56   60   66   70   78   80   84   88   90   96
102  104  108  112  114  120  126  132  138  140  150  156  160  168  174  176  180  186  192  198
204  208  210  216  220  222  224  228  234  240  246  252  258  260  264  270  272  276  280  282
294  300  304  306  308  312  318  320  330  336  340  342  348  350  352  354  360  364  366  368
372  378  380  384  390  396  402  408  414  416  420  426  432  438  440  444  448  456  460  462
464  468  474  476  480  486  490  492  496  498  500  504  510  516  520  522  528  532  534  540
544  546  550  552  558  560  564  570  572  580  582  588  594  600  606  608  612  616  618  620
624  630  636  640  642  644  650  654  660  666  672  678  680  684  690  696  700  702  704  708
714  720  726  728  732  736  740  744  750  756  760  762  768  770  780  786  792  798  804  810
812  816  820  822  828  832  834  836  840  852  858  860  864  868  870  876  880  888  894  896
906  910  912  918  920  924  928  930  936  940  942  945  948  952  960  966  972  978  980  984

First 40 odd Zumkeller numbers:
945  1575  2205  2835  3465  4095  4725  5355  5775  5985
6435  6615  6825  7245  7425  7875  8085  8415  8505  8925
9135  9555  9765 10395 11655 12285 12705 12915 13545 14175
14805 15015 15435 16065 16695 17325 17955 18585 19215 19305

First 40 odd Zumkeller numbers that do not end in a 5:
81081  153153  171171  189189  207207  223839  243243  261261  279279  297297
351351  459459  513513  567567  621621  671517  729729  742203  783783  793611
812889  837837  891891  908523  960687  999999 1024947 1054053 1072071 1073709
1095633 1108107 1145529 1162161 1198197 1224531 1270269 1307691 1324323 1378377```

## Lobster

`import std // Derived from Julia and Python versions def get_divisors(n: int) -> [int]:    var i = 2    let d = [1, n]    let limit = sqrt(n)    while i <= limit:        if n % i == 0:            let j = n / i            push(d,i)            if i != j:                push(d,j)        i += 1    return d def isPartSum(divs: [int], sum: int) -> bool:    if sum == 0:        return true    let len = length(divs)    if len == 0:        return false    let last = pop(divs)    if last > sum:        return isPartSum(divs, sum)    return isPartSum(copy(divs), sum) or isPartSum(divs, sum-last) def isZumkeller(n: int) -> bool:    let divs = get_divisors(n)    let sum = fold(divs, 0): _a+_b    if sum % 2 == 1:        // if sum is odd can't be split into two partitions with equal sums        return false    if n % 2 == 1:        // if n is odd use 'abundant odd number' optimization        let abundance = sum - 2 * n        return abundance > 0 and abundance % 2 == 0    return isPartSum(divs, sum/2) def printZumkellers(q: int, oddonly: bool):    var nprinted = 0    var res = ""    for(100000) n:        if (!oddonly or n % 2 != 0):            if isZumkeller(n):                let s = string(n)                let z = length(s)                res = concat_string([res, repeat_string(" ",8-z), s], "")                nprinted += 1                if nprinted % 10 == 0 or nprinted >= q:                    print res                    res = ""                    if nprinted >= q:                        return print "220 Zumkeller numbers:"printZumkellers(220, false)print "\n\n40 odd Zumkeller numbers:"printZumkellers(40, true) `
Output:
```220 Zumkeller numbers:
6      12      20      24      28      30      40      42      48      54
56      60      66      70      78      80      84      88      90      96
102     104     108     112     114     120     126     132     138     140
150     156     160     168     174     176     180     186     192     198
204     208     210     216     220     222     224     228     234     240
246     252     258     260     264     270     272     276     280     282
294     300     304     306     308     312     318     320     330     336
340     342     348     350     352     354     360     364     366     368
372     378     380     384     390     396     402     408     414     416
420     426     432     438     440     444     448     456     460     462
464     468     474     476     480     486     490     492     496     498
500     504     510     516     520     522     528     532     534     540
544     546     550     552     558     560     564     570     572     580
582     588     594     600     606     608     612     616     618     620
624     630     636     640     642     644     650     654     660     666
672     678     680     684     690     696     700     702     704     708
714     720     726     728     732     736     740     744     750     756
760     762     768     770     780     786     792     798     804     810
812     816     820     822     828     832     834     836     840     852
858     860     864     868     870     876     880     888     894     896
906     910     912     918     920     924     928     930     936     940
942     945     948     952     960     966     972     978     980     984

40 odd Zumkeller numbers:
945    1575    2205    2835    3465    4095    4725    5355    5775    5985
6435    6615    6825    7245    7425    7875    8085    8415    8505    8925
9135    9555    9765   10395   11655   12285   12705   12915   13545   14175
14805   15015   15435   16065   16695   17325   17955   18585   19215   19305
```

## Mathematica / Wolfram Language

`ClearAll[ZumkellerQ]ZumkellerQ[n_] := Module[{d = Divisors[n], t, ds, x},   ds = Total[d];   If[Mod[ds, 2] == 1,    False    ,    t = CoefficientList[Product[1 + x^i, {i, d}], x];    t[[1 + ds/2]] > 0    ]   ];i = 1;res = {};While[Length[res] < 220,  r = ZumkellerQ[i];  If[r, AppendTo[res, i]];  i++;  ];res i = 1;res = {};While[Length[res] < 40,  r = ZumkellerQ[i];  If[r, AppendTo[res, i]];  i += 2;  ];res`
Output:
```{6,12,20,24,28,30,40,42,48,54,56,60,66,70,78,80,84,88,90,96,102,104,108,112,114,120,126,132,138,140,150,156,160,168,174,176,180,186,192,198,204,208,210,216,220,222,224,228,234,240,246,252,258,260,264,270,272,276,280,282,294,300,304,306,308,312,318,320,330,336,340,342,348,350,352,354,360,364,366,368,372,378,380,384,390,396,402,408,414,416,420,426,432,438,440,444,448,456,460,462,464,468,474,476,480,486,490,492,496,498,500,504,510,516,520,522,528,532,534,540,544,546,550,552,558,560,564,570,572,580,582,588,594,600,606,608,612,616,618,620,624,630,636,640,642,644,650,654,660,666,672,678,680,684,690,696,700,702,704,708,714,720,726,728,732,736,740,744,750,756,760,762,768,770,780,786,792,798,804,810,812,816,820,822,828,832,834,836,840,852,858,860,864,868,870,876,880,888,894,896,906,910,912,918,920,924,928,930,936,940,942,945,948,952,960,966,972,978,980,984}
{945,1575,2205,2835,3465,4095,4725,5355,5775,5985,6435,6615,6825,7245,7425,7875,8085,8415,8505,8925,9135,9555,9765,10395,11655,12285,12705,12915,13545,14175,14805,15015,15435,16065,16695,17325,17955,18585,19215,19305}```

## Nim

Translation of: Go
`import math, strutils template isEven(n: int): bool = (n and 1) == 0template isOdd(n: int): bool = (n and 1) != 0  func getDivisors(n: int): seq[int] =  result = @[1, n]  for i in 2..sqrt(n.toFloat).int:    if n mod i == 0:      let j = n div i      result.add i      if i != j: result.add j  func isPartSum(divs: seq[int]; sum: int): bool =  if sum == 0: return true  if divs.len == 0: return false  let last = divs[^1]  let divs = divs[0..^2]  result = isPartSum(divs, sum)  if not result and last <= sum:    result = isPartSum(divs, sum - last)  func isZumkeller(n: int): bool =  let divs = n.getDivisors()  let sum = sum(divs)  # If "sum" is odd, it can't be split into two partitions with equal sums.  if sum.isOdd: return false  # If "n" is odd use "abundant odd number" optimization.  if n.isOdd:    let abundance = sum - 2 * n    return abundance > 0 and abundance.isEven  # If "n" and "sum" are both even, check if there's a partition which totals "sum / 2".  result = isPartSum(divs, sum div 2)  when isMainModule:   echo "The first 220 Zumkeller numbers are:"  var n = 2  var count = 0  while count < 220:    if n.isZumkeller:      stdout.write align(\$n, 3)      inc count      stdout.write if count mod 20 == 0: '\n' else: ' '    inc n  echo()   echo "The first 40 odd Zumkeller numbers are:"  n = 3  count = 0  while count < 40:    if n.isZumkeller:      stdout.write align(\$n, 5)      inc count      stdout.write if count mod 10 == 0: '\n' else: ' '    inc n, 2  echo()   echo "The first 40 odd Zumkeller numbers which don't end in 5 are:"  n = 3  count = 0  while count < 40:    if n mod 10 != 5 and n.isZumkeller:      stdout.write align(\$n, 7)      inc count      stdout.write if count mod 8 == 0: '\n' else: ' '    inc n, 2`
Output:
```The first 220 Zumkeller numbers are:
6  12  20  24  28  30  40  42  48  54  56  60  66  70  78  80  84  88  90  96
102 104 108 112 114 120 126 132 138 140 150 156 160 168 174 176 180 186 192 198
204 208 210 216 220 222 224 228 234 240 246 252 258 260 264 270 272 276 280 282
294 300 304 306 308 312 318 320 330 336 340 342 348 350 352 354 360 364 366 368
372 378 380 384 390 396 402 408 414 416 420 426 432 438 440 444 448 456 460 462
464 468 474 476 480 486 490 492 496 498 500 504 510 516 520 522 528 532 534 540
544 546 550 552 558 560 564 570 572 580 582 588 594 600 606 608 612 616 618 620
624 630 636 640 642 644 650 654 660 666 672 678 680 684 690 696 700 702 704 708
714 720 726 728 732 736 740 744 750 756 760 762 768 770 780 786 792 798 804 810
812 816 820 822 828 832 834 836 840 852 858 860 864 868 870 876 880 888 894 896
906 910 912 918 920 924 928 930 936 940 942 945 948 952 960 966 972 978 980 984

The first 40 odd Zumkeller numbers are:
945  1575  2205  2835  3465  4095  4725  5355  5775  5985
6435  6615  6825  7245  7425  7875  8085  8415  8505  8925
9135  9555  9765 10395 11655 12285 12705 12915 13545 14175
14805 15015 15435 16065 16695 17325 17955 18585 19215 19305

The first 40 odd Zumkeller numbers which don't end in 5 are:
81081  153153  171171  189189  207207  223839  243243  261261
279279  297297  351351  459459  513513  567567  621621  671517
729729  742203  783783  793611  812889  837837  891891  908523
960687  999999 1024947 1054053 1072071 1073709 1095633 1108107
1145529 1162161 1198197 1224531 1270269 1307691 1324323 1378377```

## Pascal

Using sieve for primedecomposition
Now using the trick, that one partition sum must include n and improved recursive search.
Limit is ~1.2e11

`program zumkeller;//https://oeis.org/A083206/a083206.txt{\$IFDEF FPC}  {\$MODE DELPHI}  {\$OPTIMIZATION ON,ALL}  {\$COPERATORS ON}//  {\$O+,I+}{\$ELSE}  {\$APPTYPE CONSOLE}{\$ENDIF}uses  sysutils{\$IFDEF WINDOWS},Windows{\$ENDIF}  ;//######################################################################//prime decompositionconst//HCN(86) > 1.2E11 = 128,501,493,120     count of divs = 4096   7 3 1 1 1 1 1 1 1  HCN_DivCnt  = 4096;//stop never ending recursion   RECCOUNTMAX = 100*1000*1000;  DELTAMAX    = 1000*1000;type  tItem     = Uint64;  tDivisors = array [0..HCN_DivCnt-1] of tItem;  tpDivisor = pUint64;const  SizePrDeFe = 12697;//*72 <= 1 or 2 Mb ~ level 2 cache -32kB for DIVStype  tdigits    = packed record                 dgtDgts : array [0..31] of Uint32;               end;   //the first number with 11 different divisors =  // 2*3*5*7*11*13*17*19*23*29*31 = 2E11  tprimeFac = packed record                 pfSumOfDivs,                 pfRemain  : Uint64;  //n div (p[0]^[pPot[0] *...) can handle primes <=821641^2 = 6.7e11                 pfpotPrim : array[0..9] of UInt32;//+10*4 = 56 Byte                 pfpotMax  : array[0..9] of byte;  //10  = 66                 pfMaxIdx  : Uint16; //68                 pfDivCnt  : Uint32; //72               end;   tPrimeDecompField = array[0..SizePrDeFe-1] of tprimeFac;  tPrimes = array[0..65535] of Uint32; var  SmallPrimes: tPrimes;//######################################################################//prime decompositionprocedure InitSmallPrimes;//only odd numbersconst  MAXLIMIT = (821641-1) shr 1;var  pr : array[0..MAXLIMIT] of byte;  p,j,d,flipflop :NativeUInt;Begin  SmallPrimes[0] := 2;  fillchar(pr[0],SizeOf(pr),#0);  p := 0;  repeat    repeat      p +=1    until pr[p]= 0;    j := (p+1)*p*2;    if j>MAXLIMIT then      BREAK;    d := 2*p+1;    repeat      pr[j] := 1;      j += d;    until j>MAXLIMIT;  until false;   SmallPrimes[1] := 3;  SmallPrimes[2] := 5;  j := 3;  d := 7;  flipflop := 3-1;  p := 3;  repeat    if pr[p] = 0 then    begin      SmallPrimes[j] := d;      inc(j);    end;    d += 2*flipflop;    p+=flipflop;    flipflop := 3-flipflop;  until (p > MAXLIMIT) OR (j>High(SmallPrimes));end; function OutPots(const pD:tprimeFac;n:NativeInt):Ansistring;var  s: String[31];Begin  str(n,s);  result := s+' :';  with pd do  begin    str(pfDivCnt:3,s);    result += s+' : ';    For n := 0 to pfMaxIdx-1 do    Begin      if n>0 then        result += '*';      str(pFpotPrim[n],s);      result += s;      if pfpotMax[n] >1 then      Begin        str(pfpotMax[n],s);        result += '^'+s;      end;    end;    If pfRemain >1 then    Begin      str(pfRemain,s);      result += '*'+s;    end;    str(pfSumOfDivs,s);    result += '_SoD_'+s+'<';  end;end; function CnvtoBASE(var dgt:tDigits;n:Uint64;base:NativeUint):NativeInt;//n must be multiple of basevar  q,r: Uint64;  i : NativeInt;Begin  with dgt do  Begin    fillchar(dgtDgts,SizeOf(dgtDgts),#0);    i := 0;//    dgtNum:= n;    n := n div base;    result := 0;    repeat      r := n;      q := n div base;      r  -= q*base;      n := q;      dgtDgts[i] := r;      inc(i);    until (q = 0);     result := 0;    while (result<i) AND (dgtDgts[result] = 0) do      inc(result);    inc(result);  end;end; function IncByBaseInBase(var dgt:tDigits;base:NativeInt):NativeInt;var  q :NativeInt;Begin  with dgt do  Begin    result := 0;    q := dgtDgts[result]+1;//    inc(dgtNum,base);    if q = base then    begin      repeat        dgtDgts[result] := 0;        inc(result);        q := dgtDgts[result]+1;      until q <> base;    end;    dgtDgts[result] := q;    result +=1;  end;end; procedure SieveOneSieve(var pdf:tPrimeDecompField;n:nativeUInt);var  dgt:tDigits;  i, j, k,pr,fac : NativeUInt;begin  //init  for i := 0 to High(pdf) do    with pdf[i] do    Begin      pfDivCnt := 1;      pfSumOfDivs := 1;      pfRemain := n+i;      pfMaxIdx := 0;    end;   //first 2 make n+i even  i := n AND 1;  repeat    with pdf[i] do      if n+i > 0 then      begin        j := BsfQWord(n+i);        pfMaxIdx := 1;        pfpotPrim[0] := 2;        pfpotMax[0] := j;        pfRemain := (n+i) shr j;        pfSumOfDivs := (1 shl (j+1))-1;        pfDivCnt := j+1;      end;    i += 2;  until i >High(pdf);   // i now index in SmallPrimes  i := 0;  repeat    //search next prime that is in bounds of sieve    repeat      inc(i);      if i >= High(SmallPrimes) then        BREAK;      pr := SmallPrimes[i];      k := pr-n MOD pr;      if (k = pr) AND (n>0) then        k:= 0;      if k < SizePrDeFe then        break;    until false;    if i >= High(SmallPrimes) then      BREAK;    //no need to use higher primes    if pr*pr > n+SizePrDeFe then      BREAK;     // j is power of prime    j := CnvtoBASE(dgt,n+k,pr);    repeat      with pdf[k] do      Begin        pfpotPrim[pfMaxIdx] := pr;        pfpotMax[pfMaxIdx] := j;        pfDivCnt *= j+1;        fac := pr;        repeat          pfRemain := pfRemain DIV pr;          dec(j);          fac *= pr;        until j<= 0;        pfSumOfDivs *= (fac-1)DIV(pr-1);        inc(pfMaxIdx);      end;      k += pr;      j := IncByBaseInBase(dgt,pr);    until k >= SizePrDeFe;  until false;   //correct sum of & count of divisors  for i := 0 to High(pdf) do  Begin    with pdf[i] do    begin      j := pfRemain;      if j <> 1 then      begin        pfSumOFDivs *= (j+1);        pfDivCnt *=2;      end;    end;  end;end;//prime decomposition//######################################################################procedure Init_Check_rec(const pD:tprimeFac;var Divs,SumOfDivs:tDivisors);forward; var{\$ALIGN 32}  PrimeDecompField:tPrimeDecompField;{\$ALIGN 32}  Divs :tDivisors;  SumOfDivs : tDivisors;  DivUsedIdx : tDivisors;   pDiv :tpDivisor;  T0: Int64;  count,rec_Cnt: NativeInt;  depth : Int32;  finished :Boolean; procedure Check_rek_depth(SoD : Int64;i: NativeInt);var  sum : Int64;begin  if finished then    EXIT;  inc(rec_Cnt);   WHILE (i>0) AND (pDiv[i]>SoD) do    dec(i);   while i >= 0 do  Begin    DivUsedIdx[depth] := pDiv[i];    sum := SoD-pDiv[i];    if sum = 0 then    begin      finished := true;      EXIT;    end;    dec(i);    inc(depth);    if (i>= 0) AND (sum <= SumOfDivs[i]) then      Check_rek_depth(sum,i);    if finished then      EXIT;//  DivUsedIdx[depth] := 0;    dec(depth);  end;end; procedure Out_One_Sol(const pd:tprimefac;n:NativeUInt;isZK : Boolean);var  sum : NativeInt;Begin  if n< 7 then    exit;  with pd do  begin    writeln(OutPots(pD,n));    if isZK then    Begin      Init_Check_rec(pD,Divs,SumOfDivs);      Check_rek_depth(pfSumOfDivs shr 1-n,pFDivCnt-1);      write(pfSumOfDivs shr 1:10,' = ');      sum := n;      while depth >= 0 do      Begin        sum += DivUsedIdx[depth];        write(DivUsedIdx[depth],'+');        dec(depth);      end;      write(n,' =  ',sum);    end    else      write(' no zumkeller ');  end;end; procedure InsertSort(pDiv:tpDivisor; Left, Right : NativeInt );var  I, J: NativeInt;  Pivot : tItem;begin  for i:= 1 + Left to Right do  begin    Pivot:= pDiv[i];    j:= i - 1;    while (j >= Left) and (pDiv[j] > Pivot) do    begin      pDiv[j+1]:=pDiv[j];      Dec(j);    end;    pDiv[j+1]:= pivot;  end;end; procedure GetDivs(const pD:tprimeFac;var Divs,SumOfDivs:tDivisors);var  pDivs : tpDivisor;  pPot : UInt64;  i,len,j,l,p,k: Int32;Begin  i := pD.pfDivCnt;  pDivs := @Divs[0];  pDivs[0] := 1;  len := 1;  l   := 1;  with pD do  Begin    For i := 0 to pfMaxIdx-1 do    begin      //Multiply every divisor before with the new primefactors      //and append them to the list      k := pfpotMax[i];      p := pfpotPrim[i];      pPot :=1;      repeat        pPot *= p;        For j := 0 to len-1 do        Begin          pDivs[l]:= pPot*pDivs[j];          inc(l);        end;        dec(k);      until k<=0;      len := l;    end;    p := pfRemain;    If p >1 then    begin      For j := 0 to len-1 do      Begin        pDivs[l]:= p*pDivs[j];        inc(l);      end;      len := l;    end;  end;  //Sort. Insertsort much faster than QuickSort in this special case  InsertSort(pDivs,0,len-1);   pPot := 0;  For i := 0 to len-1 do  begin    pPot += pDivs[i];    SumOfDivs[i] := pPot;  end;end; procedure Init_Check_rec(const pD:tprimeFac;var Divs,SumOfDivs:tDivisors);begin  GetDivs(pD,Divs,SUmOfDivs);  finished := false;  depth := 0;  pDiv := @Divs[0];end; procedure Check_rek(SoD : Int64;i: NativeInt);var  sum : Int64;begin  if finished then    EXIT;  if rec_Cnt >RECCOUNTMAX then  begin    rec_Cnt := -1;    finished := true;    exit;  end;  inc(rec_Cnt);   WHILE (i>0) AND (pDiv[i]>SoD) do    dec(i);   while i >= 0 do  Begin    sum := SoD-pDiv[i];    if sum = 0 then    begin      finished := true;      EXIT;    end;    dec(i);    if (i>= 0) AND (sum <= SumOfDivs[i]) then      Check_rek(sum,i);    if finished then      EXIT; end;end; function GetZumKeller(n: NativeUint;var pD:tPrimefac): boolean;var  SoD,sum : Int64;  Div_cnt,i,pracLmt: NativeInt;begin  rec_Cnt := 0;  SoD:= pd.pfSumOfDivs;  //sum must be even and n not deficient  if Odd(SoD) or (SoD<2*n) THEN    EXIT(false);//if Odd(n) then Exit(Not(odd(sum)));// to be tested   SoD := SoD shr 1-n;  If SoD < 2 then //0,1 is always true    Exit(true);   Div_cnt := pD.pfDivCnt;   if Not(odd(n)) then    if ((n mod 18) in [6,12]) then      EXIT(true);   //Now one needs to get the divisors  Init_check_rec(pD,Divs,SumOfDivs);   pracLmt:= 0;  if Not(odd(n)) then  begin    For i := 1 to Div_Cnt do    Begin      sum := SumOfDivs[i];      If (sum+1<Divs[i+1]) AND (sum<SoD) then      Begin        pracLmt := i;        BREAK;      end;     IF (sum>=SoD) then break;    end;    if pracLmt = 0 then      Exit(true);  end;  //number is practical followed by one big prime  if pracLmt = (Div_Cnt-1) shr 1 then  begin    i := SoD mod Divs[pracLmt+1];    with pD do    begin      if pfRemain > 1 then        EXIT((pfRemain<=i) OR (i<=sum))      else        EXIT((pfpotPrim[pfMaxIdx-1]<=i)OR (i<=sum));    end;  end;   Begin    IF Div_cnt <= HCN_DivCnt then    Begin      Check_rek(SoD,Div_cnt-1);      IF rec_Cnt = -1 then        exit(true);      exit(finished);    end;  end;  result := false;end; var  Ofs,i,n : NativeUInt;  Max: NativeUInt; procedure Init_Sieve(n:NativeUint);//Init Sieve i,oFs are Globalbegin  i := n MOD SizePrDeFe;  Ofs := (n DIV SizePrDeFe)*SizePrDeFe;  SieveOneSieve(PrimeDecompField,Ofs);end; procedure GetSmall(MaxIdx:Int32);var  ZK: Array of Uint32;  idx: UInt32;Begin  If MaxIdx<1 then    EXIT;  writeln('The first ',MaxIdx,' zumkeller numbers');  Init_Sieve(0);  setlength(ZK,MaxIdx);  idx := Low(ZK);  repeat    if GetZumKeller(n,PrimeDecompField[i]) then    Begin      ZK[idx] := n;      inc(idx);    end;    inc(i);    inc(n);    If i > High(PrimeDecompField) then    begin      dec(i,SizePrDeFe);      inc(ofs,SizePrDeFe);      SieveOneSieve(PrimeDecompField,Ofs);    end;  until idx >= MaxIdx;  For idx := 0 to MaxIdx-1 do  begin    if idx MOD 20 = 0 then      writeln;    write(ZK[idx]:4);  end;  setlength(ZK,0);  writeln;  writeln;end; procedure GetOdd(MaxIdx:Int32);var  ZK: Array of Uint32;  idx: UInt32;Begin  If MaxIdx<1 then    EXIT;  writeln('The first odd 40 zumkeller numbers');  n := 1;  Init_Sieve(n);  setlength(ZK,MaxIdx);  idx := Low(ZK);  repeat    if GetZumKeller(n,PrimeDecompField[i]) then    Begin      ZK[idx] := n;      inc(idx);    end;    inc(i,2);    inc(n,2);    If i > High(PrimeDecompField) then    begin      dec(i,SizePrDeFe);      inc(ofs,SizePrDeFe);      SieveOneSieve(PrimeDecompField,Ofs);    end;  until idx >= MaxIdx;  For idx := 0 to MaxIdx-1 do  begin    if idx MOD (80 DIV 8) = 0 then      writeln;    write(ZK[idx]:8);  end;  setlength(ZK,0);  writeln;  writeln;end; procedure GetOddNot5(MaxIdx:Int32);var  ZK: Array of Uint32;  idx: UInt32;Begin  If MaxIdx<1 then    EXIT;  writeln('The first odd 40 zumkeller numbers not ending in 5');  n := 1;  Init_Sieve(n);  setlength(ZK,MaxIdx);  idx := Low(ZK);  repeat    if GetZumKeller(n,PrimeDecompField[i]) then    Begin      ZK[idx] := n;      inc(idx);    end;    inc(i,2);    inc(n,2);    If n mod 5 = 0 then    begin      inc(i,2);      inc(n,2);    end;    If i > High(PrimeDecompField) then    begin      dec(i,SizePrDeFe);      inc(ofs,SizePrDeFe);      SieveOneSieve(PrimeDecompField,Ofs);    end;  until idx >= MaxIdx;  For idx := 0 to MaxIdx-1 do  begin    if idx MOD (80 DIV 8) = 0 then      writeln;    write(ZK[idx]:8);  end;  setlength(ZK,0);  writeln;  writeln;end;BEGIN  InitSmallPrimes;   T0 := GetTickCount64;  GetSmall(220);  GetOdd(40);  GetOddNot5(40);   writeln;  n := 1;//8996229720;//1;  Init_Sieve(n);  writeln('Start ',n,' at ',i);  T0 := GetTickCount64;  MAX := (n DIV DELTAMAX+1)*DELTAMAX;  count := 0;  repeat    writeln('Count of zumkeller numbers up to ',MAX:12);    repeat      if GetZumKeller(n,PrimeDecompField[i]) then        inc(count);      inc(i);      inc(n);      If i > High(PrimeDecompField) then      begin        dec(i,SizePrDeFe);        inc(ofs,SizePrDeFe);        SieveOneSieve(PrimeDecompField,Ofs);      end;    until n > MAX;    writeln(n-1:10,' tested found ',count:10,' ratio ',count/n:10:7);    MAX += DELTAMAX;  until MAX>10*DELTAMAX;  writeln('runtime ',(GetTickCount64-T0)/1000:8:3,' s');  writeln;  writeln('Count of recursion 59,641,327 for 8,996,229,720');  n := 8996229720;  Init_Sieve(n);  T0 := GetTickCount64;  Out_One_Sol(PrimeDecompField[i],n,true);  writeln;  writeln('runtime ',(GetTickCount64-T0)/1000:8:3,' s');END. `
Output:
```TIO.RUN
The first 220 zumkeller numbers

6  12  20  24  28  30  40  42  48  54  56  60  66  70  78  80  84  88  90  96
102 104 108 112 114 120 126 132 138 140 150 156 160 168 174 176 180 186 192 198
204 208 210 216 220 222 224 228 234 240 246 252 258 260 264 270 272 276 280 282
294 300 304 306 308 312 318 320 330 336 340 342 348 350 352 354 360 364 366 368
372 378 380 384 390 396 402 408 414 416 420 426 432 438 440 444 448 456 460 462
464 468 474 476 480 486 490 492 496 498 500 504 510 516 520 522 528 532 534 540
544 546 550 552 558 560 564 570 572 580 582 588 594 600 606 608 612 616 618 620
624 630 636 640 642 644 650 654 660 666 672 678 680 684 690 696 700 702 704 708
714 720 726 728 732 736 740 744 750 756 760 762 768 770 780 786 792 798 804 810
812 816 820 822 828 832 834 836 840 852 858 860 864 868 870 876 880 888 894 896
906 910 912 918 920 924 928 930 936 940 942 945 948 952 960 966 972 978 980 984

The first odd 40 zumkeller numbers

945    1575    2205    2835    3465    4095    4725    5355    5775    5985
6435    6615    6825    7245    7425    7875    8085    8415    8505    8925
9135    9555    9765   10395   11655   12285   12705   12915   13545   14175
14805   15015   15435   16065   16695   17325   17955   18585   19215   19305

The first odd 40 zumkeller numbers not ending in 5

81081  153153  171171  189189  207207  223839  243243  261261  279279  297297
351351  459459  513513  567567  621621  671517  729729  742203  783783  793611
812889  837837  891891  908523  960687  999999 1024947 1054053 1072071 1073709
1095633 1108107 1145529 1162161 1198197 1224531 1270269 1307691 1324323 1378377

Start 1 at 1
Count of zumkeller numbers up to      1000000
1000000 tested found     229026 ratio  0.2290258
Count of zumkeller numbers up to      2000000
2000000 tested found     457658 ratio  0.2288289
Count of zumkeller numbers up to      3000000
3000000 tested found     686048 ratio  0.2286826
Count of zumkeller numbers up to      4000000
4000000 tested found     914806 ratio  0.2287014
Count of zumkeller numbers up to      5000000
5000000 tested found    1143521 ratio  0.2287042
Count of zumkeller numbers up to      6000000
6000000 tested found    1372208 ratio  0.2287013
Count of zumkeller numbers up to      7000000
7000000 tested found    1600977 ratio  0.2287110
Count of zumkeller numbers up to      8000000
8000000 tested found    1829932 ratio  0.2287415
Count of zumkeller numbers up to      9000000
9000000 tested found    2058883 ratio  0.2287648
Count of zumkeller numbers up to     10000000
10000000 tested found    2287889 ratio  0.2287889
runtime    1.268 s
//zumkeller number with highest recursion count til 1e11
Count of recursion 59,641,327 for 8,996,229,720
8996229720 : 96 : 2^3*3^2*5*2237*11171_SoD_29253435120<
14626717560 = 36+45+60+72+90+120+180+360+201330+804312+805320+2010780+4021560+1124528715+4498114860+8996229720 =  14626717560
runtime    7.068 s  // at home 9.5s

Real time: 8.689 s  CPU share: 98.74 %

//at home til 1e11 with 85 numbers with recursion count > 1e8
9900000000 tested found 2262797501 ratio  0.2285654 recursion 10.479
runtime   48.805 s
Count of zumkeller numbers up to  10000000000
rek_ -1 @ 9998443080 : 96 : 2^3*3^2*5*3041*9133_SoD_32509184760<

10000000000 tested found 2285655276 ratio  0.2285655 recursion 10.520
runtime   28.976 s

real  40m7,478s user  40m7,039s sys 0m0,057s
only 4 til 4,512,612,672
out_1e10.txt:104: rek_ -1 @ 584818848 : 72 : 2^5*3^2*1423*1427_SoD_1665413568<
out_1e10.txt:105: rek_ -1 @ 589754016 : 72 : 2^5*3^2*1429*1433_SoD_1679457780<
out_1e10.txt:174: rek_ -1 @ 1956249450 : 72 : 2*3^2*5^2*2083*2087_SoD_5260832928<
out_1e10.txt:291: rek_ -1 @ 4512612672 : 84 : 2^6*3^2*2797*2801_SoD_12943833396<
```

## Perl

Library: ntheory
`use strict;use warnings;use feature 'say';use ntheory <is_prime divisor_sum divisors vecsum forcomb lastfor>; sub in_columns {    my(\$columns, \$values) = @_;    my @v = split ' ', \$values;    my \$width = int(80/\$columns);    printf "%\${width}d"x\$columns."\n", @v[\$_*\$columns .. -1+(1+\$_)*\$columns] for 0..-1+@v/\$columns;    print "\n";} sub is_Zumkeller {    my(\$n) = @_;    return 0 if is_prime(\$n);    my @divisors = divisors(\$n);    return 0 unless @divisors > 2 && 0 == @divisors % 2;    my \$sigma = divisor_sum(\$n);    return 0 unless 0 == \$sigma%2 && (\$sigma/2) >= \$n;    if (1 == \$n%2) {        return 1    } else {        my \$Z = 0;        forcomb { \$Z++, lastfor if vecsum(@divisors[@_]) == \$sigma/2 } @divisors;        return \$Z;    }} use constant Inf  => 1e10; say 'First 220 Zumkeller numbers:';my \$n = 0; my \$z;\$z .= do { \$n < 220 ? (is_Zumkeller(\$_) and ++\$n and "\$_ ") : last } for 1 .. Inf;in_columns(20, \$z); say 'First 40 odd Zumkeller numbers:';\$n = 0; \$z = '';\$z .= do { \$n < 40 ? (!!(\$_%2) and is_Zumkeller(\$_) and ++\$n and "\$_ ") : last } for 1 .. Inf;in_columns(10, \$z); say 'First 40 odd Zumkeller numbers not divisible by 5:';\$n = 0; \$z = '';\$z .= do { \$n < 40 ? (!!(\$_%2 and \$_%5) and is_Zumkeller(\$_) and ++\$n and "\$_ ") : last } for 1 .. Inf;in_columns(10, \$z);`
Output:
```First 220 Zumkeller numbers:
6  12  20  24  28  30  40  42  48  54  56  60  66  70  78  80  84  88  90  96
102 104 108 112 114 120 126 132 138 140 150 156 160 168 174 176 180 186 192 198
204 208 210 216 220 222 224 228 234 240 246 252 258 260 264 270 272 276 280 282
294 300 304 306 308 312 318 320 330 336 340 342 348 350 352 354 360 364 366 368
372 378 380 384 390 396 402 408 414 416 420 426 432 438 440 444 448 456 460 462
464 468 474 476 480 486 490 492 496 498 500 504 510 516 520 522 528 532 534 540
544 546 550 552 558 560 564 570 572 580 582 588 594 600 606 608 612 616 618 620
624 630 636 640 642 644 650 654 660 666 672 678 680 684 690 696 700 702 704 708
714 720 726 728 732 736 740 744 750 756 760 762 768 770 780 786 792 798 804 810
812 816 820 822 828 832 834 836 840 852 858 860 864 868 870 876 880 888 894 896
906 910 912 918 920 924 928 930 936 940 942 945 948 952 960 966 972 978 980 984

First 40 odd Zumkeller numbers:
945    1575    2205    2835    3465    4095    4725    5355    5775    5985
6435    6615    6825    7245    7425    7875    8085    8415    8505    8925
9135    9555    9765   10395   11655   12285   12705   12915   13545   14175
14805   15015   15435   16065   16695   17325   17955   18585   19215   19305

First 40 odd Zumkeller numbers not divisible by 5:
81081  153153  171171  189189  207207  223839  243243  261261  279279  297297
351351  459459  513513  567567  621621  671517  729729  742203  783783  793611
812889  837837  891891  908523  960687  999999 1024947 1054053 1072071 1073709
1095633 1108107 1145529 1162161 1198197 1224531 1270269 1307691 1324323 1378377```

## Phix

Translation of: Go
```function isPartSum(sequence f, integer l, t)
if t=0 then return true end if
if l=0 then return false end if
integer last = f[l]
return (t>=last and isPartSum(f, l-1, t-last))
or isPartSum(f, l-1, t)
end function

function isZumkeller(integer n)
sequence f = factors(n,1)
integer t = sum(f)
-- an odd sum cannot be split into two equal sums
if remainder(t,2)=1 then return false end if
-- if n is odd use 'abundant odd number' optimization
if remainder(n,2)=1 then
integer abundance := t - 2*n
return abundance>0 and remainder(abundance,2)=0
end if
-- if n and t both even check for any partition of t/2
return isPartSum(f, length(f), t/2)
end function

sequence tests = {{220,1,0,20,"%3d "},
{40,2,0,10,"%5d "},
{40,2,5,8,"%7d "}}
integer lim, step, rem, cr; string fmt
for t=1 to length(tests) do
{lim, step, rem, cr, fmt} = tests[t]
string odd = iff(step=1?"":"odd "),
wch = iff(rem=0?"":"which don't end in 5 ")
printf(1,"The first %d %sZumkeller numbers %sare:\n",{lim,odd,wch})
integer i = step+1, count = 0
while count<lim do
if (rem=0 or remainder(i,10)!=rem)
and isZumkeller(i) then
printf(1,fmt,i)
count += 1
if remainder(count,cr)=0 then puts(1,"\n") end if
end if
i += step
end while
printf(1,"\n")
end for
```
Output:
```The first 220 Zumkeller numbers are:
6  12  20  24  28  30  40  42  48  54  56  60  66  70  78  80  84  88  90  96
102 104 108 112 114 120 126 132 138 140 150 156 160 168 174 176 180 186 192 198
204 208 210 216 220 222 224 228 234 240 246 252 258 260 264 270 272 276 280 282
294 300 304 306 308 312 318 320 330 336 340 342 348 350 352 354 360 364 366 368
372 378 380 384 390 396 402 408 414 416 420 426 432 438 440 444 448 456 460 462
464 468 474 476 480 486 490 492 496 498 500 504 510 516 520 522 528 532 534 540
544 546 550 552 558 560 564 570 572 580 582 588 594 600 606 608 612 616 618 620
624 630 636 640 642 644 650 654 660 666 672 678 680 684 690 696 700 702 704 708
714 720 726 728 732 736 740 744 750 756 760 762 768 770 780 786 792 798 804 810
812 816 820 822 828 832 834 836 840 852 858 860 864 868 870 876 880 888 894 896
906 910 912 918 920 924 928 930 936 940 942 945 948 952 960 966 972 978 980 984

The first 40 odd Zumkeller numbers are:
945  1575  2205  2835  3465  4095  4725  5355  5775  5985
6435  6615  6825  7245  7425  7875  8085  8415  8505  8925
9135  9555  9765 10395 11655 12285 12705 12915 13545 14175
14805 15015 15435 16065 16695 17325 17955 18585 19215 19305

The first 40 odd Zumkeller numbers which don't end in 5 are:
81081  153153  171171  189189  207207  223839  243243  261261
279279  297297  351351  459459  513513  567567  621621  671517
729729  742203  783783  793611  812889  837837  891891  908523
960687  999999 1024947 1054053 1072071 1073709 1095633 1108107
1145529 1162161 1198197 1224531 1270269 1307691 1324323 1378377
```

Aside: not that it really matters here, but passing an explicit length to isPartSum (ie, l) is generally quite a bit faster than trimming (and therefore cloning) the contents of f, just so that we can rely on length(f), and obviously that would get more significant were f much longer, though it does in fact max out at a mere 80 here.
In contrast, reversing the "or" tests on the final return of isPartSum() has a significant detrimental effect, since it triggers a full recursive search for almost all l=0 failures before ever letting a single t=0 succeed. Quite why I don't get anything like the same slowdown when I modify the Go code is beyond me...

## PicoLisp

`(de propdiv (N)   (make      (for I N         (and (=0 (% N I)) (link I)) ) ) )(de sum? (G L)   (cond      ((=0 G) T)      ((= (car L) G) T)      ((cdr L)         (if (> (car L) G)            (sum? G (cdr L))            (or               (sum? (- G (car L)) (cdr L))               (sum? G (cdr L)) ) ) ) ) )(de zum? (N)   (let (L (propdiv N)  S (sum prog L))      (and         (not (bit? 1 S))         (if (bit? 1 N)            (let A (- S (* 2 N))               (and (gt0 A) (not (bit? 1 A)))            )            (sum?               (- (/ S 2) (car L))               (cdr L) ) ) ) ) )(zero C)(for (I 2 (> 220 C) (inc I))   (when (zum? I)      (prin (align 3 I) " ")      (inc 'C)      (and         (=0 (% C 20))         (prinl) ) ) )(prinl)(zero C)(for (I 1 (> 40 C) (inc 'I 2))   (when (zum? I)      (prin (align 9 I) " ")      (inc 'C)      (and         (=0 (% C 8))         (prinl) ) ) )(prinl)(zero C)# cheater(for (I 81079 (> 40 C) (inc 'I 2))   (when (and (<> 5 (% I 10)) (zum? I))      (prin (align 9 I) " ")      (inc 'C)      (and         (=0 (% C 8))         (prinl) ) ) )`
Output:
```  6  12  20  24  28  30  40  42  48  54  56  60  66  70  78  80  84  88  90  96
102 104 108 112 114 120 126 132 138 140 150 156 160 168 174 176 180 186 192 198
204 208 210 216 220 222 224 228 234 240 246 252 258 260 264 270 272 276 280 282
294 300 304 306 308 312 318 320 330 336 340 342 348 350 352 354 360 364 366 368
372 378 380 384 390 396 402 408 414 416 420 426 432 438 440 444 448 456 460 462
464 468 474 476 480 486 490 492 496 498 500 504 510 516 520 522 528 532 534 540
544 546 550 552 558 560 564 570 572 580 582 588 594 600 606 608 612 616 618 620
624 630 636 640 642 644 650 654 660 666 672 678 680 684 690 696 700 702 704 708
714 720 726 728 732 736 740 744 750 756 760 762 768 770 780 786 792 798 804 810
812 816 820 822 828 832 834 836 840 852 858 860 864 868 870 876 880 888 894 896
906 910 912 918 920 924 928 930 936 940 942 945 948 952 960 966 972 978 980 984

945      1575      2205      2835      3465      4095      4725      5355
5775      5985      6435      6615      6825      7245      7425      7875
8085      8415      8505      8925      9135      9555      9765     10395
11655     12285     12705     12915     13545     14175     14805     15015
15435     16065     16695     17325     17955     18585     19215     19305

81081    153153    171171    189189    207207    223839    243243    261261
279279    297297    351351    459459    513513    567567    621621    671517
729729    742203    783783    793611    812889    837837    891891    908523
960687    999999   1024947   1054053   1072071   1073709   1095633   1108107
1145529   1162161   1198197   1224531   1270269   1307691   1324323   1378377
```

## Python

### Procedural

Modified from a footnote at OEIS A083207 (see reference in problem text) by Charles R Greathouse IV.

`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) `
Output:
```220 Zumkeller numbers:
6      12      20      24      28      30      40      42      48      54
56      60      66      70      78      80      84      88      90      96
102     104     108     112     114     120     126     132     138     140
150     156     160     168     174     176     180     186     192     198
204     208     210     216     220     222     224     228     234     240
246     252     258     260     264     270     272     276     280     282
294     300     304     306     308     312     318     320     330     336
340     342     348     350     352     354     360     364     366     368
372     378     380     384     390     396     402     408     414     416
420     426     432     438     440     444     448     456     460     462
464     468     474     476     480     486     490     492     496     498
500     504     510     516     520     522     528     532     534     540
544     546     550     552     558     560     564     570     572     580
582     588     594     600     606     608     612     616     618     620
624     630     636     640     642     644     650     654     660     666
672     678     680     684     690     696     700     702     704     708
714     720     726     728     732     736     740     744     750     756
760     762     768     770     780     786     792     798     804     810
812     816     820     822     828     832     834     836     840     852
858     860     864     868     870     876     880     888     894     896
906     910     912     918     920     924     928     930     936     940
942     945     948     952     960     966     972     978     980     984

40 odd Zumkeller numbers:
945    1575    2205    2835    3465    4095    4725    5355    5775    5985
6435    6615    6825    7245    7425    7875    8085    8415    8505    8925
9135    9555    9765   10395   11655   12285   12705   12915   13545   14175
14805   15015   15435   16065   16695   17325   17955   18585   19215   19305
```

### Functional

Relying on the standard Python libraries, as an alternative to importing SymPy:

`'''Zumkeller numbers''' from itertools import (    accumulate, chain, count, groupby, islice, product)from functools import reducefrom math import floor, sqrtimport operator  # ---------------------- ZUMKELLER ----------------------- # isZumkeller :: Int -> Booldef isZumkeller(n):    '''True if there exists a disjoint partition       of the divisors of m, such that the two sets have       the same sum.       (In other words, if n is in OEIS A083207)    '''    ds = divisors(n)    m = sum(ds)    if even(m):        half = m // 2        return half in ds or (            all(map(ge(half), ds)) and (                summable(half, ds)            )        )    else:        return False  # summable :: Int -> [Int] -> Booldef summable(x, xs):    '''True if any subset of the sorted       list xs sums to x.    '''    if xs:        if x in xs:            return True        else:            t = xs[1:]            return summable(x - xs[0], t) or summable(x, t)    else:        return False  # ------------------------- TEST -------------------------# main :: IO ()def main():    '''First 220 Zumkeller numbers,       and first 40 odd Zumkellers.    '''     tenColumns = tabulated(10)     print('First 220 Zumkeller numbers:\n')    print(tenColumns(        take(220)(            filter(isZumkeller, count(1))        )    ))    print('\nFirst 40 odd Zumkeller numbers:\n')    print(tenColumns(        take(40)(            filter(isZumkeller, enumFromThen(1)(3))        )    ))  # ---------------------- TABULATION ---------------------- # tabulated :: Int -> [a] -> Stringdef tabulated(nCols):    '''String representation of a list       of values as rows of n columns.    '''    def go(xs):        ts = [str(x) for x in xs]        w = 1 + max(len(x) for x in ts)        return '\n'.join([            ''.join(row) for row            in chunksOf(nCols)([                t.rjust(w, ' ') for t in ts            ])        ])    return go  # ----------------------- GENERIC ------------------------ # chunksOf :: Int -> [a] -> [[a]]def chunksOf(n):    '''A series of lists of length n, subdividing the       contents of xs. Where the length of xs is not evenly       divible, the final list will be shorter than n.    '''    def go(xs):        return (            xs[i:n + i] for i in range(0, len(xs), n)        ) if 0 < n else None    return go  # divisors :: Int -> [Int]def divisors(n):    '''The ordered divisors of n.    '''    def go(a, x):        return [a * b for a, b in product(            a,            accumulate(chain([1], x), operator.mul)        )]    return sorted(        reduce(go, [            list(g) for _, g in groupby(primeFactors(n))        ], [1])    ) if 1 < n else [1]  # enumFromThen :: Int -> Int -> [Int]def enumFromThen(m):    '''A non-finite stream of integers       starting at m, and continuing       at the interval between m and n.    '''    return lambda n: count(m, n - m)  # even :: Int -> Booldef even(x):    '''True if x is an integer       multiple of two.    '''    return 0 == x % 2  # ge :: Eq a => a -> a -> Booldef ge(a):    def go(b):        return operator.ge(a, b)    return go  # primeFactors :: Int -> [Int]def primeFactors(n):    '''A list of the prime factors of n.    '''    def f(qr):        r = qr[1]        return step(r), 1 + r     def step(x):        return 1 + (x << 2) - ((x >> 1) << 1)     def go(x):        root = floor(sqrt(x))         def p(qr):            q = qr[0]            return root < q or 0 == (x % q)         q = until(p)(f)(            (2 if 0 == x % 2 else 3, 1)        )[0]        return [x] if q > root else [q] + go(x // q)     return go(n)  # take :: Int -> [a] -> [a]# take :: Int -> String -> Stringdef take(n):    '''The prefix of xs of length n,       or xs itself if n > length xs.    '''    def go(xs):        return (            xs[0:n]            if isinstance(xs, (list, tuple))            else list(islice(xs, n))        )    return go  # until :: (a -> Bool) -> (a -> a) -> a -> adef until(p):    '''The result of repeatedly applying f until p holds.       The initial seed value is x.    '''    def go(f):        def g(x):            v = x            while not p(v):                v = f(v)            return v        return g    return go  # MAIN ---if __name__ == '__main__':    main()`
Output:
```First 220 Zumkeller numbers:

6  12  20  24  28  30  40  42  48  54
56  60  66  70  78  80  84  88  90  96
102 104 108 112 114 120 126 132 138 140
150 156 160 168 174 176 180 186 192 198
204 208 210 216 220 222 224 228 234 240
246 252 258 260 264 270 272 276 280 282
294 300 304 306 308 312 318 320 330 336
340 342 348 350 352 354 360 364 366 368
372 378 380 384 390 396 402 408 414 416
420 426 432 438 440 444 448 456 460 462
464 468 474 476 480 486 490 492 496 498
500 504 510 516 520 522 528 532 534 540
544 546 550 552 558 560 564 570 572 580
582 588 594 600 606 608 612 616 618 620
624 630 636 640 642 644 650 654 660 666
672 678 680 684 690 696 700 702 704 708
714 720 726 728 732 736 740 744 750 756
760 762 768 770 780 786 792 798 804 810
812 816 820 822 828 832 834 836 840 852
858 860 864 868 870 876 880 888 894 896
906 910 912 918 920 924 928 930 936 940
942 945 948 952 960 966 972 978 980 984

First 40 odd Zumkeller numbers:

945  1575  2205  2835  3465  4095  4725  5355  5775  5985
6435  6615  6825  7245  7425  7875  8085  8415  8505  8925
9135  9555  9765 10395 11655 12285 12705 12915 13545 14175
14805 15015 15435 16065 16695 17325 17955 18585 19215 19305```

## Racket

Translation of: Zkl
`#lang racket (require math/number-theory) (define (zum? n)  (let* ((set (divisors n))         (sum (apply + set)))    (cond      [(odd? sum) #f]      [(odd? n) ; if n is odd use 'abundant odd number' optimization       (let ((abundance (- sum (* n 2)))) (and (positive? abundance) (even? abundance)))]      [else       (let ((sum/2 (quotient sum 2)))         (let loop ((acc (car set)) (set (cdr set)))           (cond [(= acc sum/2) #t]                 [(> acc sum/2) #f]                 [(null? set) #f]                 [else (or (loop (+ (car set) acc) (cdr set))                           (loop acc (cdr set)))])))]))) (define (first-n-matching-naturals count pred)  (for/list ((i count) (j (stream-filter pred (in-naturals 1)))) j)) (define (tabulate title ns (row-width 132))  (displayln title)  (let* ((cell-width (+ 2 (order-of-magnitude (apply max ns))))         (cells/row (quotient row-width cell-width)))    (let loop ((ns ns) (col cells/row))      (cond [(null? ns) (unless (= col cells/row) (newline))]            [(zero? col) (newline) (loop ns cells/row)]            [else (display (~a #:width cell-width #:align 'right (car ns)))                  (loop (cdr ns) (sub1 col))]))))  (tabulate  "First 220 Zumkeller numbers:" (first-n-matching-naturals 220 zum?))(newline)(tabulate "First 40 odd Zumkeller numbers:"          (first-n-matching-naturals 40 (λ (n) (and (odd? n) (zum? n)))))(newline)(tabulate "First 40 odd Zumkeller numbers not ending in 5:"          (first-n-matching-naturals 40 (λ (n) (and (odd? n) (not (= 5 (modulo n 10))) (zum? n)))))`
Output:
```First 220 Zumkeller numbers:
6  12  20  24  28  30  40  42  48  54  56  60  66  70  78  80  84  88  90  96 102 104 108 112 114 120 126 132 138 140 150 156 160
168 174 176 180 186 192 198 204 208 210 216 220 222 224 228 234 240 246 252 258 260 264 270 272 276 280 282 294 300 304 306 308 312
318 320 330 336 340 342 348 350 352 354 360 364 366 368 372 378 380 384 390 396 402 408 414 416 420 426 432 438 440 444 448 456 460
462 464 468 474 476 480 486 490 492 496 498 500 504 510 516 520 522 528 532 534 540 544 546 550 552 558 560 564 570 572 580 582 588
594 600 606 608 612 616 618 620 624 630 636 640 642 644 650 654 660 666 672 678 680 684 690 696 700 702 704 708 714 720 726 728 732
736 740 744 750 756 760 762 768 770 780 786 792 798 804 810 812 816 820 822 828 832 834 836 840 852 858 860 864 868 870 876 880 888
894 896 906 910 912 918 920 924 928 930 936 940 942 945 948 952 960 966 972 978 980 984

First 40 odd Zumkeller numbers:
945  1575  2205  2835  3465  4095  4725  5355  5775  5985  6435  6615  6825  7245  7425  7875  8085  8415  8505  8925  9135  9555
9765 10395 11655 12285 12705 12915 13545 14175 14805 15015 15435 16065 16695 17325 17955 18585 19215 19305

First 40 odd Zumkeller numbers not ending in 5:
81081  153153  171171  189189  207207  223839  243243  261261  279279  297297  351351  459459  513513  567567  621621  671517
729729  742203  783783  793611  812889  837837  891891  908523  960687  999999 1024947 1054053 1072071 1073709 1095633 1108107
1145529 1162161 1198197 1224531 1270269 1307691 1324323 1378377```

## Raku

(formerly Perl 6)

Works with: Rakudo version 2019.07.1
`use ntheory:from<Perl5> <factor is_prime>; sub zumkeller (\$range)  {    \$range.grep: -> \$maybe {        next if \$maybe < 3;        next if \$maybe.&is_prime;        my @divisors = \$maybe.&factor.combinations».reduce( &[*] ).unique.reverse;        next unless [&&] +@divisors > 2, +@divisors %% 2, (my \$sum = sum @divisors) %% 2, (\$sum /= 2) >= \$maybe;        my \$zumkeller = False;        if \$maybe % 2 {            \$zumkeller = True        } else {            TEST: loop (my \$c = 1; \$c < @divisors / 2; ++\$c) {                @divisors.combinations(\$c).map: -> \$d {                    next if (sum \$d) != \$sum;                    \$zumkeller = True and last TEST;                }            }        }        \$zumkeller    }} say "First 220 Zumkeller numbers:\n" ~    zumkeller(^Inf)[^220].rotor(20)».fmt('%3d').join: "\n"; put "\nFirst 40 odd Zumkeller numbers:\n" ~    zumkeller((^Inf).map: * * 2 + 1)[^40].rotor(10)».fmt('%7d').join: "\n"; # Stretch. Slow to calculate. (minutes) put "\nFirst 40 odd Zumkeller numbers not divisible by 5:\n" ~    zumkeller(flat (^Inf).map: {my \p = 10 * \$_; p+1, p+3, p+7, p+9} )[^40].rotor(10)».fmt('%7d').join: "\n";`
Output:
```First 220 Zumkeller numbers:
6  12  20  24  28  30  40  42  48  54  56  60  66  70  78  80  84  88  90  96
102 104 108 112 114 120 126 132 138 140 150 156 160 168 174 176 180 186 192 198
204 208 210 216 220 222 224 228 234 240 246 252 258 260 264 270 272 276 280 282
294 300 304 306 308 312 318 320 330 336 340 342 348 350 352 354 360 364 366 368
372 378 380 384 390 396 402 408 414 416 420 426 432 438 440 444 448 456 460 462
464 468 474 476 480 486 490 492 496 498 500 504 510 516 520 522 528 532 534 540
544 546 550 552 558 560 564 570 572 580 582 588 594 600 606 608 612 616 618 620
624 630 636 640 642 644 650 654 660 666 672 678 680 684 690 696 700 702 704 708
714 720 726 728 732 736 740 744 750 756 760 762 768 770 780 786 792 798 804 810
812 816 820 822 828 832 834 836 840 852 858 860 864 868 870 876 880 888 894 896
906 910 912 918 920 924 928 930 936 940 942 945 948 952 960 966 972 978 980 984

First 40 odd Zumkeller numbers:
945    1575    2205    2835    3465    4095    4725    5355    5775    5985
6435    6615    6825    7245    7425    7875    8085    8415    8505    8925
9135    9555    9765   10395   11655   12285   12705   12915   13545   14175
14805   15015   15435   16065   16695   17325   17955   18585   19215   19305

First 40 odd Zumkeller numbers not divisible by 5:
81081  153153  171171  189189  207207  223839  243243  261261  279279  297297
351351  459459  513513  567567  621621  671517  729729  742203  783783  793611
812889  837837  891891  908523  960687  999999 1024947 1054053 1072071 1073709
1095633 1108107 1145529 1162161 1198197 1224531 1270269 1307691 1324323 1378377```

## REXX

The construction of the partitions were created in the order in which the most likely partitions would match.

`/*REXX pgm finds & shows Zumkeller numbers: 1st N; 1st odd M; 1st odd V not ending in 5.*/parse arg n m v .                                /*obtain optional arguments from the CL*/if n=='' | n==","  then n= 220                   /*Not specified?  Then use the default.*/if m=='' | m==","  then m=  40                   /* "      "         "   "   "     "    */if v=='' | v==","  then v=  40                   /* "      "         "   "   "     "    */@zum= ' Zumkeller numbers are: '                 /*literal used for displaying messages.*/sw= linesize() - 1                               /*obtain the usable screen width.      */sayif n>0  then say center(' The first '       n       @zum,  sw, "═")#= 0                                             /*the count of Zumkeller numbers so far*/\$=                                               /*initialize the  \$  list  (to a null).*/        do j=1  until #==n                       /*traipse through integers 'til done.  */        if \Zum(j)  then iterate                 /*if not a Zumkeller number, then skip.*/        #= # + 1;           call add\$            /*bump Zumkeller count;  add to \$ list.*/        end   /*j*/ if \$\==''  then say \$                            /*Are there any residuals? Then display*/sayif m>0  then say center(' The first odd '   m       @zum,  sw, "═")#= 0                                             /*the count of Zumkeller numbers so far*/\$=                                               /*initialize the  \$  list  (to a null).*/        do j=1  by 2  until #==m                 /*traipse through integers 'til done.  */        if \Zum(j)  then iterate                 /*if not a Zumkeller number, then skip.*/        #= # + 1;           call add\$            /*bump Zumkeller count;  add to \$ list.*/        end   /*j*/ if \$\==''  then say \$                            /*Are there any residuals? Then display*/sayif v>0  then say center(' The first odd '   v       " (not ending in 5) " @zum,  sw, '═')#= 0                                             /*the count of Zumkeller numbers so far*/\$=                                               /*initialize the  \$  list  (to a null).*/        do j=1  by 2  until #==v                 /*traipse through integers 'til done.  */        if right(j,1)==5  then iterate           /*skip if odd number ends in digit "5".*/        if \Zum(j)  then iterate                 /*if not a Zumkeller number, then skip.*/        #= # + 1;           call add\$            /*bump Zumkeller count;  add to \$ list.*/        end   /*j*/ if \$\==''  then say \$                            /*Are there any residuals? Then display*/exit                                             /*stick a fork in it,  we're all done. *//*──────────────────────────────────────────────────────────────────────────────────────*/add\$: _= strip(\$ j, 'L');   if length(_)<sw  then do;  \$= _;  return;  end    /*add to \$*/      say  strip(\$, 'L');                              \$= j;  return          /*say, add*//*──────────────────────────────────────────────────────────────────────────────────────*/iSqrt: procedure; parse arg x;  r= 0;  q= 1;                    do while q<=x; q=q*4;  end          do while q>1; q= q%4; _= x-r-q; r= r%2; if _>=0  then do; x= _; r= r+q; end; end       return r                                  /*R  is the integer square root of  X. *//*──────────────────────────────────────────────────────────────────────────────────────*/PDaS: procedure; parse arg x 1 b;  odd= x//2     /*obtain  X  and  B (the 1st argument).*/      if x==1  then return 1 1                   /*handle special case for unity.       */      r= iSqrt(x)                                /*calculate integer square root of  X. */      a= 1                                       /* [↓]  use all, or only odd numbers.  */      sig= a + b                                 /*initialize the sigma  (so far)   ___ */          do j=2+odd  by 1+odd  to r - (r*r==x)  /*divide by some integers up to   √ X  */          if x//j==0  then do;  a=a j;  b= x%j b /*if ÷, add both divisors to α & ß.    */                                sig= sig +j +x%j /*bump the sigma (the sum of divisors).*/                           end          end   /*j*/                            /* [↑]  %  is the REXX integer division*/                                                 /* [↓]  adjust for a square.        ___*/      if j*j==x  then  return sig+j  a j b       /*Was  X  a square?    If so, add  √ X */                       return sig    a   b       /*return the divisors  (both lists).   *//*──────────────────────────────────────────────────────────────────────────────────────*/Zum:  procedure; parse arg x .                   /*obtain a # to be tested for Zumkeller*/      if x<6    then return 0                    /*test if X is too low     "      "    */      if x<945  then if x//2==1  then return 0   /*  "   " "  "  "   "  for odd    "    */      parse value  PDaS(x)  with  sigma pdivs    /*obtain sigma and the proper divisors.*/      if sigma//2  then return 0                 /*Is the  sigma  odd?    Not Zumkeller.*/      #= words(pdivs)                            /*count the number of divisors for  X. */      if #<3       then return 0                 /*Not enough divisors?    "      "     */      if x//2      then do; _= sigma - x - x     /*use abundant optimization for odd #'s*/                            return _>0 & _//2==0 /*Abundant is > 0 and even?  It's a Zum*/                        end      if #>23      then return 1                 /*# divisors is 24 or more?  It's a Zum*/            do i=1  for #;   @.i= word(pdivs, i)  /*assign proper divisors to the @ array*/           end   /*i*/      c=0;            u= 2**#;   !.= .          do p=1  for u-2;       b= x2b(d2x(p))  /*convert P──►binary with leading zeros*/          b= right(strip(b, 'L', 0), #, 0)       /*ensure enough leading zeros for  B.  */          r= reverse(b); if !.r\==. then iterate /*is this binary# a palindrome of prev?*/          c= c + 1;   yy.c= b;   !.b=            /*store this particular combination.   */          end   /*p*/           do part=1  for c;      p1= 0;   p2= 0  /*test of two partitions add to same #.*/          _= yy.part                             /*obtain one method of partitioning.   */            do cp=1  for #                       /*obtain the sums of the two partitions*/            if substr(_, cp, 1)  then p1= p1 + @.cp     /*if a  one, then add it to  P1.*/                                 else p2= p2 + @.cp     /* " " zero,   "   "   "  "  P2.*/            end   /*cp*/          if p1==p2  then return 1               /*Partition sums equal?  Then X is Zum.*/          end   /*part*/      return 0                                   /*no partition sum passed.  X isn't Zum*/`
output   when using the default inputs:
```══════════════════════════════════════════════ The first  220  Zumkeller numbers are: ═══════════════════════════════════════════════
6 12 20 24 28 30 40 42 48 54 56 60 66 70 78 80 84 88 90 96 102 104 108 112 114 120 126 132 138 140 150 156 160 168 174 176 180 186
192 198 204 208 210 216 220 222 224 228 234 240 246 252 258 260 264 270 272 276 280 282 294 300 304 306 308 312 318 320 330 336 340
342 348 350 352 354 360 364 366 368 372 378 380 384 390 396 402 408 414 416 420 426 432 438 440 444 448 456 460 462 464 468 474 476
480 486 490 492 496 498 500 504 510 516 520 522 528 532 534 540 544 546 550 552 558 560 564 570 572 580 582 588 594 600 606 608 612
616 618 620 624 630 636 640 642 644 650 654 660 666 672 678 680 684 690 696 700 702 704 708 714 720 726 728 732 736 740 744 750 756
760 762 768 770 780 786 792 798 804 810 812 816 820 822 828 832 834 836 840 852 858 860 864 868 870 876 880 888 894 896 906 910 912
918 920 924 928 930 936 940 942 945 948 952 960 966 972 978 980 984

═════════════════════════════════════════════ The first odd  40  Zumkeller numbers are: ═════════════════════════════════════════════
945 1575 2205 2835 3465 4095 4725 5355 5775 5985 6435 6615 6825 7245 7425 7875 8085 8415 8505 8925 9135 9555 9765 10395 11655 12285
12705 12915 13545 14175 14805 15015 15435 16065 16695 17325 17955 18585 19215 19305

═══════════════════════════════════ The first odd  40  (not ending in 5)   Zumkeller numbers are: ═══════════════════════════════════
81081 153153 171171 189189 207207 223839 243243 261261 279279 297297 351351 459459 513513 567567 621621 671517 729729 742203 783783
793611 812889 837837 891891 908523 960687 999999 1024947 1054053 1072071 1073709 1095633 1108107 1145529 1162161 1198197 1224531
1270269 1307691 1324323 1378377
```

## Ring

` load "stdlib.ring" see "working..." + nlsee "The first 220 Zumkeller numbers are:" + nl permut = []zumind = []zumodd = []limit = 19305num1 = 0num2 = 0 for n = 2 to limit    zumkeller = []    zumList = []    permut = []    calmo = []    zumind = []    num = 0    nold = 0    for m = 1 to n        if n % m = 0            num = num + 1           add(zumind,m)        ok    next    for p = 1 to num        add(zumList,1)        add(zumList,2)    next    permut(zumList)    lenZum = len(zumList)     for n2 = 1 to len(permut)/lenZum         str = ""        for m = (n2-1)*lenZum+1 to n2*lenZum            str = str + string(permut[m])        next        if str != ""           strNum = number(str)           add(calmo,strNum)        ok    next     calmo = sort(calmo)     for x = len(calmo) to 2 step -1        if calmo[x] = calmo[x-1]           del(calmo,x)        ok    next     zumkeller = []    calmoLen = len(string(calmo[1]))    calmoLen2 = calmoLen/2    for y = 1 to len(calmo)        tmpStr = string(calmo[y])        tmp1 = left(tmpStr,calmoLen2)        tmp2 = number(tmp1)        add(zumkeller,tmp2)    next     zumkeller = sort(zumkeller)     for x = len(zumkeller) to 2 step -1        if zumkeller[x] = zumkeller[x-1]           del(zumkeller,x)        ok    next     for z = 1 to len(zumkeller)        zumsum1 = 0        zumsum2 = 0        zum1 = []        zum2 = []         for m = 1 to len(string(zumkeller[z]))            zumstr = string(zumkeller[z])            tmp = number(zumstr[m])            if tmp = 1               add(zum1,zumind[m])            else               add(zum2,zumind[m])            ok        next          for z1 = 1 to len(zum1)            zumsum1 = zumsum1 + zum1[z1]        next         for z2 = 1 to len(zum2)            zumsum2 = zumsum2 + zum2[z2]        next         if zumsum1 = zumsum2           num1 = num1 + 1           if n != nold              if num1 < 221                 if (n-1)%22 = 0                    see nl + " " + n                 else                    see " " + n                 ok              ok              if zumsum1%2 = 1                 num2 = num2 + 1                 if num2 < 41                    add(zumodd,n)                 ok              ok           ok           nold = n        ok    next    next see "The first 40 odd Zumkeller numbers are:" + nlfor n = 1 to len(zumodd)    if (n-1)%8 = 0       see nl + " " + zumodd[n]    else       see " " + zumodd[n]    oknext see nl + "done..." + nl func permut(list)     for perm = 1 to factorial(len(list))         for i = 1 to len(list)             add(permut,list[i])         next         perm(list)     next func perm(a)     elementcount = len(a)     if elementcount < 1         return      ok     pos = elementcount-1     while a[pos] >= a[pos+1]            pos -= 1           if pos <= 0 permutationReverse(a, 1, elementcount)              return           ok     end     last = elementcount     while a[last] <= a[pos]           last -= 1     end     temp = a[pos]     a[pos] = a[last]     a[last] = temp     permReverse(a, pos+1, elementcount)  func permReverse(a,first,last)      while first < last            temp = a[first]            a[first] = a[last]            a[last] = temp            first += 1            last -= 1      end `

Output:

```working...
The first 220 Zumkeller numbers are:
6   12  20  24  28  30  40  42  48  54  56  60  66  70  78  80  84  88  90  96
102 104 108 112 114 120 126 132 138 140 150 156 160 168 174 176 180 186 192 198
204 208 210 216 220 222 224 228 234 240 246 252 258 260 264 270 272 276 280 282
294 300 304 306 308 312 318 320 330 336 340 342 348 350 352 354 360 364 366 368
372 378 380 384 390 396 402 408 414 416 420 426 432 438 440 444 448 456 460 462
464 468 474 476 480 486 490 492 496 498 500 504 510 516 520 522 528 532 534 540
544 546 550 552 558 560 564 570 572 580 582 588 594 600 606 608 612 616 618 620
624 630 636 640 642 644 650 654 660 666 672 678 680 684 690 696 700 702 704 708
714 720 726 728 732 736 740 744 750 756 760 762 768 770 780 786 792 798 804 810
812 816 820 822 828 832 834 836 840 852 858 860 864 868 870 876 880 888 894 896
906 910 912 918 920 924 928 930 936 940 942 945 948 952 960 966 972 978 980 984
The first 40 odd Zumkeller numbers are:
945     1575    2205    2835    3465    4095    4725    5355
5775    5985    6435    6615    6825    7245    7425    7875
8085    8415    8505    8925    9135    9555    9765    10395
11655   12285   12705   12915   13545   14175   14805   15015
15435   16065   16695   17325   17955   18585   19215   19305
done...
```

## Ruby

`class Integer   def divisors    res = [1, self]    (2..Integer.sqrt(self)).each do |n|      div, mod = divmod(n)      res << n << div if mod.zero?    end    res.uniq.sort  end   def zumkeller?    divs = divisors    sum  = divs.sum    return false unless sum.even? && sum >= self*2    half = sum / 2    max_combi_size = divs.size / 2    1.upto(max_combi_size).any? do |combi_size|      divs.combination(combi_size).any?{|combi| combi.sum == half}    end  end end def p_enum(enum, cols = 10, col_width = 8)  enum.each_slice(cols) {|slice| puts "%#{col_width}d"*slice.size % slice}end puts "#{n=220} Zumkeller numbers:"p_enum 1.step.lazy.select(&:zumkeller?).take(n), 14, 6 puts "\n#{n=40} odd Zumkeller numbers:"p_enum 1.step(by: 2).lazy.select(&:zumkeller?).take(n) puts "\n#{n=40} odd Zumkeller numbers not ending with 5:"p_enum 1.step(by: 2).lazy.select{|x| x % 5 > 0 && x.zumkeller?}.take(n) `
Output:
```220 Zumkeller numbers:
6    12    20    24    28    30    40    42    48    54    56    60    66    70
78    80    84    88    90    96   102   104   108   112   114   120   126   132
138   140   150   156   160   168   174   176   180   186   192   198   204   208
210   216   220   222   224   228   234   240   246   252   258   260   264   270
272   276   280   282   294   300   304   306   308   312   318   320   330   336
340   342   348   350   352   354   360   364   366   368   372   378   380   384
390   396   402   408   414   416   420   426   432   438   440   444   448   456
460   462   464   468   474   476   480   486   490   492   496   498   500   504
510   516   520   522   528   532   534   540   544   546   550   552   558   560
564   570   572   580   582   588   594   600   606   608   612   616   618   620
624   630   636   640   642   644   650   654   660   666   672   678   680   684
690   696   700   702   704   708   714   720   726   728   732   736   740   744
750   756   760   762   768   770   780   786   792   798   804   810   812   816
820   822   828   832   834   836   840   852   858   860   864   868   870   876
880   888   894   896   906   910   912   918   920   924   928   930   936   940
942   945   948   952   960   966   972   978   980   984

40 odd Zumkeller numbers:
945    1575    2205    2835    3465    4095    4725    5355    5775    5985
6435    6615    6825    7245    7425    7875    8085    8415    8505    8925
9135    9555    9765   10395   11655   12285   12705   12915   13545   14175
14805   15015   15435   16065   16695   17325   17955   18585   19215   19305

40 odd Zumkeller numbers not ending with 5:
81081  153153  171171  189189  207207  223839  243243  261261  279279  297297
351351  459459  513513  567567  621621  671517  729729  742203  783783  793611
812889  837837  891891  908523  960687  999999 1024947 1054053 1072071 1073709
1095633 1108107 1145529 1162161 1198197 1224531 1270269 1307691 1324323 1378377
```

## Rust

` use std::convert::TryInto; /// Gets all divisors of a number, including itselffn get_divisors(n: u32) -> Vec<u32> {    let mut results = Vec::new();     for i in 1..(n / 2 + 1) {        if n % i == 0 {            results.push(i);        }    }    results.push(n);    results} /// Calculates whether the divisors can be partitioned into two disjoint/// sets that sum to the same valuefn is_summable(x: i32, divisors: &[u32]) -> bool {    if !divisors.is_empty() {        if divisors.contains(&(x as u32)) {            return true;        } else if let Some((first, t)) = divisors.split_first() {            return is_summable(x - *first as i32, &t) || is_summable(x, &t);        }    }    false} /// Calculates whether the number is a Zumkeller number/// 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.fn is_zumkeller_number(number: u32) -> bool {    if number % 18 == 6 || number % 18 == 12 {        return true;    }     let div = get_divisors(number);    let divisor_sum: u32 = div.iter().sum();    if divisor_sum == 0 {        return false;    }    if divisor_sum % 2 == 1 {        return false;    }     // numbers where n is odd and the abundance is even are Zumkeller numbers    let abundance = divisor_sum as i32 - 2 * number as i32;    if number % 2 == 1 && abundance > 0 && abundance % 2 == 0 {        return true;    }     let half = divisor_sum / 2;    return div.contains(&half)        || (div.iter().filter(|&&d| d < half).count() > 0            && is_summable(half.try_into().unwrap(), &div));} fn main() {    println!("\nFirst 220 Zumkeller numbers:");    let mut counter: u32 = 0;    let mut i: u32 = 0;    while counter < 220 {        if is_zumkeller_number(i) {            print!("{:>3}", i);            counter += 1;            print!("{}", if counter % 20 == 0 { "\n" } else { "," });        }        i += 1;    }     println!("\nFirst 40 odd Zumkeller numbers:");    let mut counter: u32 = 0;    let mut i: u32 = 3;    while counter < 40 {        if is_zumkeller_number(i) {            print!("{:>5}", i);            counter += 1;            print!("{}", if counter % 20 == 0 { "\n" } else { "," });        }        i += 2;    }} `
Output:
```First 220 Zumkeller numbers:
6, 12, 20, 24, 28, 30, 40, 42, 48, 54, 56, 60, 66, 70, 78, 80, 84, 88, 90, 96
102,104,108,112,114,120,126,132,138,140,150,156,160,168,174,176,180,186,192,198
204,208,210,216,220,222,224,228,234,240,246,252,258,260,264,270,272,276,280,282
294,300,304,306,308,312,318,320,330,336,340,342,348,350,352,354,360,364,366,368
372,378,380,384,390,396,402,408,414,416,420,426,432,438,440,444,448,456,460,462
464,468,474,476,480,486,490,492,496,498,500,504,510,516,520,522,528,532,534,540
544,546,550,552,558,560,564,570,572,580,582,588,594,600,606,608,612,616,618,620
624,630,636,640,642,644,650,654,660,666,672,678,680,684,690,696,700,702,704,708
714,720,726,728,732,736,740,744,750,756,760,762,768,770,780,786,792,798,804,810
812,816,820,822,828,832,834,836,840,852,858,860,864,868,870,876,880,888,894,896
906,910,912,918,920,924,928,930,936,940,942,945,948,952,960,966,972,978,980,984
```

## Sidef

`func is_Zumkeller(n) {     return false if n.is_prime    return false if n.is_square     var sigma = n.sigma     # n must have an even abundance    return false if (sigma.is_odd || (sigma < 2*n))     # true if n is odd and has an even abundance    return true if n.is_odd    # conjecture     var divisors = n.divisors     for k in (2 .. divisors.end) {        divisors.combinations(k, {|*a|            if (2*a.sum == sigma) {                return true            }        })    }     return false} say "First 220 Zumkeller numbers:"say (1..Inf -> lazy.grep(is_Zumkeller).first(220).join(' ')) say "\nFirst 40 odd Zumkeller numbers: "say (1..Inf `by` 2 -> lazy.grep(is_Zumkeller).first(40).join(' ')) say "\nFirst 40 odd Zumkeller numbers not divisible by 5: "say (1..Inf `by` 2 -> lazy.grep { _ % 5 != 0 }.grep(is_Zumkeller).first(40).join(' '))`
Output:
```First 220 Zumkeller numbers:
6 12 20 24 28 30 40 42 48 54 56 60 66 70 78 80 84 88 90 96 102 104 108 112 114 120 126 132 138 140 150 156 160 168 174 176 180 186 192 198 204 208 210 216 220 222 224 228 234 240 246 252 258 260 264 270 272 276 280 282 294 300 304 306 308 312 318 320 330 336 340 342 348 350 352 354 360 364 366 368 372 378 380 384 390 396 402 408 414 416 420 426 432 438 440 444 448 456 460 462 464 468 474 476 480 486 490 492 496 498 500 504 510 516 520 522 528 532 534 540 544 546 550 552 558 560 564 570 572 580 582 588 594 600 606 608 612 616 618 620 624 630 636 640 642 644 650 654 660 666 672 678 680 684 690 696 700 702 704 708 714 720 726 728 732 736 740 744 750 756 760 762 768 770 780 786 792 798 804 810 812 816 820 822 828 832 834 836 840 852 858 860 864 868 870 876 880 888 894 896 906 910 912 918 920 924 928 930 936 940 942 945 948 952 960 966 972 978 980 984

First 40 odd Zumkeller numbers:
945 1575 2205 2835 3465 4095 4725 5355 5775 5985 6435 6615 6825 7245 7425 7875 8085 8415 8505 8925 9135 9555 9765 10395 11655 12285 12705 12915 13545 14175 14805 15015 15435 16065 16695 17325 17955 18585 19215 19305

First 40 odd Zumkeller numbers not divisible by 5:
81081 153153 171171 189189 207207 223839 243243 261261 279279 297297 351351 459459 513513 567567 621621 671517 729729 742203 783783 793611 812889 837837 891891 908523 960687 999999 1024947 1054053 1072071 1073709 1095633 1108107 1145529 1162161 1198197 1224531 1270269 1307691 1324323 1378377
```

## Standard ML

` exception Found of string ; val divisors  = fn n =>let val rec divr = fn  ( c, divlist ,i) =>    if c <2*i then c::divlist              else divr  (if c mod i = 0 then (c,i::divlist,i+1)  else (c,divlist,i+1) )in   divr  (n,[],1) end;  val subsetSums = fn M => fn input =>let val getnrs = fn (v,x) =>                                 (* out: list of numbers index where v is true + x *)  let     val rec runthr =  fn (v,i,x,lst)=> if i>=M then (v,i,x,lst) else  runthr (v,i+1,x,if Vector.sub(v,i) then (i+x)::lst else lst) ;  in     #4 (runthr (v,0,x,[]))  end;  val nwVec =  fn  (v,nrs) =>  let    val rec upd = fn (v,i,[])   => (v,i,[])                  | (v,i,h::t)  => upd ( case Int.compare (h,M) of		            LESS    => ( Vector.update (v,h,true),i+1,t) 		          | GREATER => (v,i+1,t)		          | EQUAL   => raise Found ("done "^(Int.toString h))  )   in    #1 (upd (v,0,nrs))  end;  val rec setSums = fn ([],v)  => ([],v)                   | (x::t,v) => setSums(t, nwVec(v, getnrs (v,x))) in   #2 (setSums (input,Vector.tabulate (M+1,fn 0=> true|_=>false) )) end;  val rec Zumkeller =  fn n =>  let   val d    =  divisors n;   val s    =  List.foldr op+ 0 d ;   val hs   =  s div 2 -n ;  in    if s mod 2 = 1 orelse 0 > hs then false else       Vector.sub (  subsetSums hs (tl d) ,hs)             handle Found nr => true end; `

call loop and output - interpreter

` - val Zumkellerlist = fn step =>   fn no5 =>let   val rec loop = fn incr => fn  (i,n,v) =>        if i=  (case  incr of 1 => 221  | 2 => 41 | _ => 5 )	        then (0,n,v)                else  if n mod 5 = 0 andalso no5 then loop incr (i,n+incr,v) else		   if Zumkeller n  then loop incr (i+1,n+incr,(i,n)::v) else loop incr (i,n+incr,v)in    rev (#3 ( loop step (1,3,[])))end;- List.app (fn x=> print (Int.toString (#2 x) ^ ", "))  (Zumkellerlist 1 false) ;6, 12, 20, 24, 28, 30, 40, 42, 48, 54, 56, 60, 66, 70, 78, 80, 84, 88, 90, 96, 102, 104, 108, 112, 114, 120, 126, 132,138, 140, 150, 156, 160, 168, 174, 176, 180, 186, 192, 198, 204, 208, 210, 216, 220, 222, 224, 228, 234, 240, 246, 252,258, 260, 264, 270, 272, 276, 280, 282, 294, 300, 304, 306, 308, 312, 318, 320, 330, 336, 340, 342, 348, 350, 352, 354,360, 364, 366, 368, 372, 378, 380, 384, 390, 396, 402, 408, 414, 416, 420, 426, 432, 438, 440, 444, 448, 456, 460, 462,464, 468, 474, 476, 480, 486, 490, 492, 496, 498, 500, 504, 510, 516, 520, 522, 528, 532, 534, 540, 544, 546, 550, 552,558, 560, 564, 570, 572, 580, 582, 588, 594, 600, 606, 608, 612, 616, 618, 620, 624, 630, 636, 640, 642, 644, 650, 654,660, 666, 672, 678, 680, 684, 690, 696, 700, 702, 704, 708, 714, 720, 726, 728, 732, 736, 740, 744, 750, 756, 760, 762,768, 770, 780, 786, 792, 798, 804, 810, 812, 816, 820, 822, 828, 832, 834, 836, 840, 852, 858, 860, 864, 868, 870, 876,880, 888, 894, 896, 906, 910, 912, 918, 920, 924, 928, 930, 936, 940, 942, 945, 948, 952, 960, 966, 972, 978, 980, 984 - List.app (fn x=> print (Int.toString (#2 x) ^ ", "))  (Zumkellerlist 2 false) ; 945, 1575, 2205, 2835, 3465, 4095, 4725, 5355, 5775, 5985, 6435, 6615, 6825, 7245, 7425, 7875, 8085, 8415, 8505, 8925,9135, 9555, 9765, 10395, 11655, 12285, 12705, 12915, 13545, 14175, 14805, 15015, 15435, 16065, 16695, 17325, 17955, 8585, 19215, 19305  -  List.app (fn x=> print (Int.toString (#2 x) ^ ", "))  (Zumkellerlist 2 true) ;81081, 153153, 171171, 189189, 207207, 223839, 243243, 261261, 279279, 297297, 351351, 459459, 513513, 567567, 621621, 671517, 729729,742203, 783783, 793611, 812889, 837837, 891891, 908523, 960687, 999999, 1024947, 1054053, 1072071, 1073709, 1095633, 1108107, 1145529,1162161, 1198197, 1224531, 1270269, 1307691, 1324323, 1378377 `

## Swift

Translation of: Go
`import Foundation extension BinaryInteger {  @inlinable  public var isZumkeller: Bool {    let divs = factors(sorted: false)    let sum = divs.reduce(0, +)     guard sum & 1 != 1 else {      return false    }     guard self & 1 != 1 else {      let abundance = sum - 2*self       return abundance > 0 && abundance & 1 == 0    }     return isPartSum(divs: divs[...], sum: sum / 2)  }   @inlinable  public func factors(sorted: Bool = true) -> [Self] {    let maxN = Self(Double(self).squareRoot())    var res = Set<Self>()     for factor in stride(from: 1, through: maxN, by: 1) where self % factor == 0 {      res.insert(factor)      res.insert(self / factor)    }     return sorted ? res.sorted() : Array(res)  }} @usableFromInlinefunc isPartSum<T: BinaryInteger>(divs: ArraySlice<T>, sum: T) -> Bool {  guard sum != 0 else {    return true  }   guard !divs.isEmpty else {    return false  }   let last = divs.last!   if last > sum {    return isPartSum(divs: divs.dropLast(), sum: sum)  }   return isPartSum(divs: divs.dropLast(), sum: sum) || isPartSum(divs: divs.dropLast(), sum: sum - last)} let zums = (2...).lazy.filter({ \$0.isZumkeller })let oddZums = zums.filter({ \$0 & 1 == 1 })let oddZumsWithout5 = oddZums.filter({ String(\$0).last! != "5" }) print("First 220 zumkeller numbers are \(Array(zums.prefix(220)))")print("First 40 odd zumkeller numbers are \(Array(oddZums.prefix(40)))")print("First 40 odd zumkeller numbers that don't end in a 5 are: \(Array(oddZumsWithout5.prefix(40)))")`
Output:
```First 220 zumkeller numbers are: [6, 12, 20, 24, 28, 30, 40, 42, 48, 54, 56, 60, 66, 70, 78, 80, 84, 88, 90, 96, 102, 104, 108, 112, 114, 120, 126, 132, 138, 140, 150, 156, 160, 168, 174, 176, 180, 186, 192, 198, 204, 208, 210, 216, 220, 222, 224, 228, 234, 240, 246, 252, 258, 260, 264, 270, 272, 276, 280, 282, 294, 300, 304, 306, 308, 312, 318, 320, 330, 336, 340, 342, 348, 350, 352, 354, 360, 364, 366, 368, 372, 378, 380, 384, 390, 396, 402, 408, 414, 416, 420, 426, 432, 438, 440, 444, 448, 456, 460, 462, 464, 468, 474, 476, 480, 486, 490, 492, 496, 498, 500, 504, 510, 516, 520, 522, 528, 532, 534, 540, 544, 546, 550, 552, 558, 560, 564, 570, 572, 580, 582, 588, 594, 600, 606, 608, 612, 616, 618, 620, 624, 630, 636, 640, 642, 644, 650, 654, 660, 666, 672, 678, 680, 684, 690, 696, 700, 702, 704, 708, 714, 720, 726, 728, 732, 736, 740, 744, 750, 756, 760, 762, 768, 770, 780, 786, 792, 798, 804, 810, 812, 816, 820, 822, 828, 832, 834, 836, 840, 852, 858, 860, 864, 868, 870, 876, 880, 888, 894, 896, 906, 910, 912, 918, 920, 924, 928, 930, 936, 940, 942, 945, 948, 952, 960, 966, 972, 978, 980, 984]
First 40 odd zumkeller numbers are: [945, 1575, 2205, 2835, 3465, 4095, 4725, 5355, 5775, 5985, 6435, 6615, 6825, 7245, 7425, 7875, 8085, 8415, 8505, 8925, 9135, 9555, 9765, 10395, 11655, 12285, 12705, 12915, 13545, 14175, 14805, 15015, 15435, 16065, 16695, 17325, 17955, 18585, 19215, 19305]
First 40 odd zumkeller numbers that don't end in a 5 are: [81081, 153153, 171171, 189189, 207207, 223839, 243243, 261261, 279279, 297297, 351351, 459459, 513513, 567567, 621621, 671517, 729729, 742203, 783783, 793611, 812889, 837837, 891891, 908523, 960687, 999999, 1024947, 1054053, 1072071, 1073709, 1095633, 1108107, 1145529, 1162161, 1198197, 1224531, 1270269, 1307691, 1324323, 1378377]```

## Visual Basic .NET

Translation of: C#
`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 SubEnd Module`
Output:
```The first 220 Zumkeller numbers are:
6  12  20  24  28  30  40  42  48  54  56  60  66  70  78  80  84  88  90  96
102 104 108 112 114 120 126 132 138 140 150 156 160 168 174 176 180 186 192 198
204 208 210 216 220 222 224 228 234 240 246 252 258 260 264 270 272 276 280 282
294 300 304 306 308 312 318 320 330 336 340 342 348 350 352 354 360 364 366 368
372 378 380 384 390 396 402 408 414 416 420 426 432 438 440 444 448 456 460 462
464 468 474 476 480 486 490 492 496 498 500 504 510 516 520 522 528 532 534 540
544 546 550 552 558 560 564 570 572 580 582 588 594 600 606 608 612 616 618 620
624 630 636 640 642 644 650 654 660 666 672 678 680 684 690 696 700 702 704 708
714 720 726 728 732 736 740 744 750 756 760 762 768 770 780 786 792 798 804 810
812 816 820 822 828 832 834 836 840 852 858 860 864 868 870 876 880 888 894 896
906 910 912 918 920 924 928 930 936 940 942 945 948 952 960 966 972 978 980 984

The first 40 odd Zumkeller numbers are:
945  1575  2205  2835  3465  4095  4725  5355  5775  5985
6435  6615  6825  7245  7425  7875  8085  8415  8505  8925
9135  9555  9765 10395 11655 12285 12705 12915 13545 14175
14805 15015 15435 16065 16695 17325 17955 18585 19215 19305

The first 40 odd Zumkeller numbers which don't end in 5 are:
81081  153153  171171  189189  207207  223839  243243  261261
279279  297297  351351  459459  513513  567567  621621  671517
729729  742203  783783  793611  812889  837837  891891  908523
960687  999999 1024947 1054053 1072071 1073709 1095633 1108107
1145529 1162161 1198197 1224531 1270269 1307691 1324323 1378377```

## Wren

Translation of: Go
Library: Wren-math
Library: Wren-fmt

I've reversed the order of the recursive calls in the last line of the isPartSum function which, as noted in the Phix entry, seems to make little difference to Go but (as one might have expected) speeds up this Wren script enormously. The first part is now near instant but was taking several minutes previously. Overall it's now only about 5.5 times slower than Go itself which is a good result for the Wren interpreter.

`import "/math" for Int, Numsimport "/fmt" for Fmtimport "io" for Stdout var isPartSum // recursiveisPartSum = Fn.new { |divs, sum|    if (sum == 0) return true    if (divs.count == 0) return false    var last = divs[-1]    divs = divs[0...-1]    if (last > sum) return isPartSum.call(divs, sum)    return isPartSum.call(divs, sum-last) || isPartSum.call(divs, sum)} var isZumkeller = Fn.new { |n|    var divs = Int.divisors(n)    var sum = Nums.sum(divs)    // if sum is odd can't be split into two partitions with equal sums    if (sum % 2 == 1) return false    // if n is odd use 'abundant odd number' optimization    if (n % 2 == 1) {        var abundance = sum - 2 * n        return abundance > 0 && abundance % 2 == 0    }    // if n and sum are both even check if there's a partition which totals sum / 2    return isPartSum.call(divs, sum / 2)} System.print("The first 220 Zumkeller numbers are:")var count = 0var i = 2while (count < 220) {    if (isZumkeller.call(i)) {        Fmt.write("\$3d ", i)        Stdout.flush()        count = count + 1        if (count % 20 ==  0) System.print()    }    i = i + 1} System.print("\nThe first 40 odd Zumkeller numbers are:")count = 0i = 3while (count < 40) {    if (isZumkeller.call(i)) {        Fmt.write("\$5d ", i)        Stdout.flush()        count = count + 1        if (count % 10 == 0) System.print()    }    i = i + 2} System.print("\nThe first 40 odd Zumkeller numbers which don't end in 5 are:")count = 0i = 3while (count < 40) {    if ((i % 10 != 5) && isZumkeller.call(i)) {        Fmt.write("\$7d ", i)        Stdout.flush()        count = count + 1        if (count % 8 == 0) System.print()    }    i = i + 2}System.print()`
Output:
```The first 220 Zumkeller numbers are:
6  12  20  24  28  30  40  42  48  54  56  60  66  70  78  80  84  88  90  96
102 104 108 112 114 120 126 132 138 140 150 156 160 168 174 176 180 186 192 198
204 208 210 216 220 222 224 228 234 240 246 252 258 260 264 270 272 276 280 282
294 300 304 306 308 312 318 320 330 336 340 342 348 350 352 354 360 364 366 368
372 378 380 384 390 396 402 408 414 416 420 426 432 438 440 444 448 456 460 462
464 468 474 476 480 486 490 492 496 498 500 504 510 516 520 522 528 532 534 540
544 546 550 552 558 560 564 570 572 580 582 588 594 600 606 608 612 616 618 620
624 630 636 640 642 644 650 654 660 666 672 678 680 684 690 696 700 702 704 708
714 720 726 728 732 736 740 744 750 756 760 762 768 770 780 786 792 798 804 810
812 816 820 822 828 832 834 836 840 852 858 860 864 868 870 876 880 888 894 896
906 910 912 918 920 924 928 930 936 940 942 945 948 952 960 966 972 978 980 984

The first 40 odd Zumkeller numbers are:
945  1575  2205  2835  3465  4095  4725  5355  5775  5985
6435  6615  6825  7245  7425  7875  8085  8415  8505  8925
9135  9555  9765 10395 11655 12285 12705 12915 13545 14175
14805 15015 15435 16065 16695 17325 17955 18585 19215 19305

The first 40 odd Zumkeller numbers which don't end in 5 are:
81081  153153  171171  189189  207207  223839  243243  261261
279279  297297  351351  459459  513513  567567  621621  671517
729729  742203  783783  793611  812889  837837  891891  908523
960687  999999 1024947 1054053 1072071 1073709 1095633 1108107
1145529 1162161 1198197 1224531 1270269 1307691 1324323 1378377
```

## zkl

Translation of: Julia
Translation of: Go
`fcn properDivs(n){ // does not include n//   if(n==1) return(T);	// we con't care about this case   ( pd:=[1..(n).toFloat().sqrt()].filter('wrap(x){ n%x==0 }) )   .pump(pd,'wrap(pd){ if(pd!=1 and (y:=n/pd)!=pd ) y else Void.Skip })}fcn canSum(goal,divs){   if(goal==0 or divs[0]==goal) return(True);   if(divs.len()>1){      if(divs[0]>goal) return(canSum(goal,divs[1,*]));  // tail recursion      else return(canSum(goal - divs[0], divs[1,*]) or canSum(goal, divs[1,*]));   }   False}fcn isZumkellerW(n){	// a filter for a iterator   ds,sum := properDivs(n), ds.sum(0) + n;   // if sum is odd, it can't be split into two partitions with equal sums   if(sum.isOdd) return(Void.Skip);   // if n is odd use 'abundant odd number' optimization   if(n.isOdd){      abundance:=sum - 2*n;      return( if(abundance>0 and abundance.isEven) n else Void.Skip);   }   canSum(sum/2,ds) and n or Void.Skip	// sum is even}`
`println("First 220 Zumkeller numbers:");zw:=[2..].tweak(isZumkellerW);do(11){ zw.walk(20).pump(String,"%4d ".fmt).println() } println("\nFirst 40 odd Zumkeller numbers:");zw:=[3..*, 2].tweak(isZumkellerW);do(4){ zw.walk(10).pump(String,"%5d ".fmt).println() } println("\nThe first 40 odd Zumkeller numbers which don't end in 5 are:");zw:=[3..*, 2].tweak(fcn(n){ if(n%5) isZumkellerW(n) else Void.Skip });do(5){ zw.walk(8).pump(String,"%7d ".fmt).println() }`
Output:
```First 220 Zumkeller numbers:
6   12   20   24   28   30   40   42   48   54   56   60   66   70   78   80   84   88   90   96
102  104  108  112  114  120  126  132  138  140  150  156  160  168  174  176  180  186  192  198
204  208  210  216  220  222  224  228  234  240  246  252  258  260  264  270  272  276  280  282
294  300  304  306  308  312  318  320  330  336  340  342  348  350  352  354  360  364  366  368
372  378  380  384  390  396  402  408  414  416  420  426  432  438  440  444  448  456  460  462
464  468  474  476  480  486  490  492  496  498  500  504  510  516  520  522  528  532  534  540
544  546  550  552  558  560  564  570  572  580  582  588  594  600  606  608  612  616  618  620
624  630  636  640  642  644  650  654  660  666  672  678  680  684  690  696  700  702  704  708
714  720  726  728  732  736  740  744  750  756  760  762  768  770  780  786  792  798  804  810
812  816  820  822  828  832  834  836  840  852  858  860  864  868  870  876  880  888  894  896
906  910  912  918  920  924  928  930  936  940  942  945  948  952  960  966  972  978  980  984

First 40 odd Zumkeller numbers:
945  1575  2205  2835  3465  4095  4725  5355  5775  5985
6435  6615  6825  7245  7425  7875  8085  8415  8505  8925
9135  9555  9765 10395 11655 12285 12705 12915 13545 14175
14805 15015 15435 16065 16695 17325 17955 18585 19215 19305

The first 40 odd Zumkeller numbers which don't end in 5 are:
81081  153153  171171  189189  207207  223839  243243  261261
279279  297297  351351  459459  513513  567567  621621  671517
729729  742203  783783  793611  812889  837837  891891  908523
960687  999999 1024947 1054053 1072071 1073709 1095633 1108107
1145529 1162161 1198197 1224531 1270269 1307691 1324323 1378377
```