Zumkeller numbers: Difference between revisions

m
 
(73 intermediate revisions by 29 users not shown)
Line 1:
{{task|Prime Numbers}}
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.
 
Line 24:
;See Also:
 
:* '''[[oeis:A083207|OEIS:A083207 - Zumkeller numbers]]''' to get an impression of different partitions '''[[oeis:A083206/a083206.txt|OEIS:A083206 Zumkeller partitions]]'''
:* '''[[oeis:A174865|OEIS:A174865 - Odd Zumkeller numbers]]'''
 
Line 32:
:* '''[[Abundant odd numbers]]'''
:* '''[[Abundant, deficient and perfect number classifications]]'''
:* '''[[Proper divisors]]''' , '''[[Factors of an integer]]'''
 
=={{header|11l}}==
{{trans|D}}
 
<syntaxhighlight lang="11l">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 = 2
V count = 0
L 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 = 3
count = 0
L 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 = 3
count = 0
L count < 40
I i % 10 != 5 & isZumkeller(i)
print(‘#7 ’.format(i), end' ‘’)
count++
I count % 8 == 0
print()
i += 2</syntaxhighlight>
 
{{out}}
<pre>
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
</pre>
 
=={{header|AArch64 Assembly}}==
{{works with|as|Raspberry Pi 3B version Buster 64 bits}}
<langsyntaxhighlight lang="AArch64 Assembly">
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program zumkellex641.s */
Line 524 ⟶ 633:
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
</syntaxhighlight>
</lang>
{{Output:}}
<pre>
Line 548 ⟶ 657:
Program normal end.
</pre>
 
=={{header|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.
 
<syntaxhighlight lang="applescript">-- 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 sum
end 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 output
end 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 zumkellers
end 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 txt
end 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 cheating
set cheating to false
doTask(cheating)</syntaxhighlight>
 
{{output}}
<syntaxhighlight lang="applescript">"1st 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
 
1st 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
 
1st 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"</syntaxhighlight>
 
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi}}
<langsyntaxhighlight lang="ARM Assembly">
 
/* ARM assembly Raspberry PI */
/* program zumkellerzumkeller4.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
/* REMARK 2 : this program is not optimized.
Not search First 40 odd Zumkeller numbers not divisible by 5 */
/*******************************************/
/* Constantes */
/*******************************************/
.equ STDOUT, 1 @ Linux output console
.equ EXIT, 1 @ Linux syscall
.equ WRITE, 4 @ Linux syscall
 
.equ NBDIVISORS, 100
 
/*******************************************/
/* Structures */
/********************************************/
/* structurea area divisors */
.struct 0
div_ident: // ident
.struct div_ident + 4
div_flag: // value 0, 1 or 2
.struct div_flag + 4
div_fin:
/*******************************************/
/* Initialized data */
Line 589 ⟶ 874:
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"
Line 602 ⟶ 890:
.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 */
Line 608 ⟶ 897:
.bss
.align 4
tbDivisorssZoneConv: .skip div_fin * NBDIVISORS // area divisors24
tbZoneDecom: .skip 8 * NBDIVISORS // facteur 4 octets, nombre 4
/*******************************************/
/* code section */
Line 618 ⟶ 908:
bl affichageMess
 
ldr r0,iAdrszMessEntete @ display result message
bl affichageMess
mov r2,#1 @ counter number
mov r3,#0 @ counter zumkeller number
mov r4,#0 @ counter for line display
1:
mov r0,r2 @ number
mov r1,#0 @ display flag
bl testZumkeller
cmp r0,#1 @ zumkeller ?
bne 3f @ no
mov r0,r2
ldr r1,iAdrsNumber @ and convert ascii string
Line 637 ⟶ 926:
cmp r4,#20
blt 2f
add r1,r1,#3 @ carriage return at end of display line
mov r0,#'\n'
strb r0,[r1]
mov r0,#0
strb r0,[r1,#1] @ end of display line
ldr r0,iAdrsNumber @ display result message
bl affichageMess
mov r4,#0
2:
add r3,r3,#1 @ increment counter
3:
add r2,r2,#1 @ increment number
cmp r3,#220 @ end ?
blt 1b
 
Line 660 ⟶ 949:
4:
mov r0,r2 @ number
mov r1,#0 @ display flag
bl testZumkeller
cmp r0,#1
Line 686 ⟶ 974:
cmp r3,#40
blt 4b
/* odd zumkeller numbers not multiple5 */
 
61:
ldr r0,iAdrszMessEntete2
bl affichageMess
mov r3,#0
mov r4,#0
7:
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,#0
8:
add r3,r3,#1
9:
add r2,r2,#2
cmp r3,#40
blt 7b
 
ldr r0,iAdrszMessEndPgm @ display end message
Line 704 ⟶ 1,039:
iAdrszMessResult: .int szMessResult
iAdrsValue: .int sValue
iAdrtbZoneDecom: .int tbZoneDecom
iAdrszMessEntete: .int szMessEntete
iAdrszMessEntete1: .int szMessEntete1
iAdrszMessEntete2: .int szMessEntete2
iAdrsNumber: .int sNumber
 
Line 712 ⟶ 1,049:
/******************************************************************/
/* r0 contains the number */
/* r1 contains display flag (<>0: display, 0: no display )
/* r0 return 1 if Zumkeller number else return 0 */
testZumkeller:
push {r1-r8r6,lr} @ save registers
mov r8r6,r0 @ save number
ldr r1,iAdrtbZoneDecom
mov r7,r1 @ save flag
bl decompFact @ create area of divisors
ldr r1,iAdrtbDivisors
blcmp divisorsr0,#1 @ create area of@ no divisors
movle r0,#0
cmp r0,#0 @ 0 divisors or error ?
movle r0,#-1
ble 100f
movtst r5r2,r0#1 @ numberodd ofsum dividers?
mov r6,r1 @ number of odd dividers
cmp r7,#1 @ display divisors ?
bne 1f
ldr r0,iAdrszMessListDivi @ yes
bl affichageMess
mov r0,r5
mov r1,#0
ldr r2,iAdrtbDivisors
bl printHeap
1:
tst r6,#1 @ number of odd divisors is odd ?
movne r0,#0 @ yes -> end
bne 100f
mov r0,r5
mov r1,#0
ldr r2,iAdrtbDivisors
bl sumDivisors @ compute divisors sum
tst r0,#1 @ sum is odd ?
movne r0,#0
bne 100f @ yes -> end
lsrtst r6,r0r1,#1 @ computenumber of odd divisors is sumodd /2?
movne r0,#0
mov r0,r6 @ r0 contains sum / 2
movbne 100f r1,#1 @ firstyes -> heapend
movlsl r3r5,r6,r5#1 @ @abondant number divisors
cmp r5,r2
mov r4,#0 @ N° element to start
movgt r0,#0
bl searchHeap
bgt 100f @ no -> end
cmp r0,#-2
mov r3,r0
beq 100f @ end
mov r4,r2 @ save sum
cmp r0,#-1
ldr r0,iAdrtbZoneDecom
beq 100f @ end
mov r1,#0
 
mov r2,r3
cmp r7,#1 @ print flag ?
bl shellSort @ sort table
bne 2f
ldr r0,iAdrszMessListDiviHeap
mov r1,r3 @ factors number
bl affichageMess
ldr r0,iAdrtbZoneDecom
mov r0,r5 @ yes print divisors of first heap
lsr r2,r4,#1 @ sum / 2
ldr r2,iAdrtbDivisors
bl computePartIter @
mov r1,#1
bl printHeap
2:
mov r0,#1 @ ok
 
100:
pop {r1-r8r6,lr} @ restaur registers
bx lr @ return
 
iAdrtbDivisors: .int tbDivisors
iAdrszMessListDiviHeap: .int szMessListDiviHeap
/******************************************************************/
/* search sumfactors divisors =to sum / 2 = entry value */
/******************************************************************/
/* r0 contains sumaddress toof searchdivisors area */
/* r1 contains elements flag (1 or 2)number */
/* r2 contains addressdivisors ofsum divisors/ 2 area */
/* r3r0 containsreturn elements1 numberif ok 0 else */
computePartIter:
/* r4 contains N° element to start */
push {r1-r7,fp,lr} @ save registers
/* r0 return -2 end search */
lsl r7,r1,#3 @ compute size of temp table
/* r0 return -1 no heap */
sub sp,r7 @ and reserve on stack
/* r0 return 0 Ok */
mov fp,sp @ frame pointer = stack address = begin table
/* recursive routine */
mov r5,#0 @ stack indice
searchHeap:
sub r3,r1,#1
push {r1-r8,lr} @ save registers
1:
cmpldr r4,[r0,r3,lsl #2] @ indice = elementsload numberfactor
moveqcmp r0r4,#-2r2 @ yes ->@ compare endvalue
beqbgt 100f2f
lslbeq 90f r6,r4,#3 @ computeequal -> elementend addressok
cmp r3,#0 @ first item ?
add r6,r2
beq 3f
ldr r7,[r6,#div_flag] @ flag equal ?
sub r3,#1 @ push indice item in temp table
cmp r7,#0
bneadd 6fr6,fp,r5,lsl #3
ldrstr r5r3,[r6,#div_ident]
cmpstr r5r2,r0 [r6,#4] @ elementpush valuesum =in remainingtemp amounttable
add r5,#1
beq 7f @ yes
bgtsub 6fr2,r4 @ substract divisors from @ too large sum
@ too less
mov r8,r0 @ save sum
sub r0,r0,r5 @ new sum to find
add r4,r4,#1 @ next divisors
bl searchHeap @ other search
cmp r0,#0 @ find -> ok
beq 5f
mov r0,r8 @ sum begin
sub r4,r4,#1 @ prev divisors
bl razFlags @ zero in all flags > current element
4:
add r4,r4,#1 @ last divisors
b 1b
2:
sub r3,#1 @ other divisors
cmp r3,#0 @ first item ?
bge 1b
3: @ 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 divisors
2:
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 @ indice
21:
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 7f
4: @ same divisor
sub r9,r4,#1
mov r7,r4
41:
ldr r10,[r5,r9,lsl #2 ]
cmp r10,r1
subne r9,#1
bne 41b
sub r9,r4,r9
42:
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:
strcmp r1,[r6,#div_flag]2 @ flagif divisor = 2 -> areaadd element1 flag
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 @ indice
71:
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 11f
9:
sub r9,r4,#1
mov r7,r4
91:
ldr r10,[r5,r9,lsl #2 ]
cmp r10,r8
subne r9,#1
bne 91b
sub r9,r4,r9
92:
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
 
6:
add r4,r4,#1 @ last divisors
98:
b 1b
//ldr r0,iAdrszMessNbPrem
7:
//bl affichageMess
str r1,[r6,#div_flag] @ flag -> area element flag
mov r0,#01 @ searchreturn okcode
b 100f
99:
ldr r0,iAdrszMessError
bl affichageMess
mov r0,#-1 @ error code
b 100f
8:
mov r0,#-1 @ end search
100:
pop {r1r3-r8,lr} @ restaur registers
bx lr @ return
iAdrszMessNbPrem: .int szMessNbPrem
/******************************************************************/
/***************************************************/
/* raz flags */
/* check if a number is prime */
/******************************************************************/
/***************************************************/
/* r0 contains sum to search */
/* r1r0 contains the number flag (1 or 2) */
/* r2r0 containsreturn address1 ofif divisorsprime area 0 else */
@2147483647
/* r3 contains elements number */
@4294967297
/* r4 contains N° element to start */
@131071
/* r5 contains sum en cours */
isPrime:
razFlags:
push {r0r1-r6,lr} @ save registers
movcmp 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 prime
1:
cmptst r4r0,r3 #1 @ indice > nb elementseven ?
bge 100f beq 90f @ yes -> endnot prime
mov r2,r0 @ save number
lsl r5,r4,#2
addsub r5r1,r5r0,r2#1 @ exposant n - @ compute address element1
ldrmov r6,[r5r0,#div_flag]3 @ load flag @ base
cmpbl r1,r6moduloPuR32 @ compute base power n - 1 modulo @ equal ?n
cmp r0,#1
streq r0,[r5,#div_flag] @ yes -> store 0
addbne r4,r4,#190f @ if <> 1 @ increment-> not indiceprime
b 1b @ and loop
mov r0,#5
100:
bl moduloPuR32
pop {r0-r6,lr} @ restaur registers
cmp r0,#1
bx lr @ return
bne 90f
/******************************************************************/
/* compute sum of divisors */
mov r0,#7
/******************************************************************/
bl moduloPuR32
/* r0 contains elements number */
cmp r0,#1
/* r1 contains flag (0 1 or 2)
bne 90f
/* r2 contains address of divisors area
/* r0 return divisors sum */
mov r0,#11
sumDivisors:
bl moduloPuR32
push {r1-r6,lr} @ save registers
cmp r0,#1
mov r3,#0 @ indice
bne 90f
mov r6,#0 @ sum
mov r0,#13
bl moduloPuR32
cmp r0,#1
bne 90f
mov r0,#17
bl moduloPuR32
cmp r0,#1
bne 90f
80:
mov r0,#1 @ is prime
b 100f
90:
mov r0,#0 @ no prime
100: @ 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 erreur
1:
lslmov r4,r3,#3 r2 @ N° element *save 8modulo
mov r5,r1 @ save exposant
add r4,r2
ldrmov r5r6,[r4,#div_flag]r0 @ compare flag @ save base
mov r3,#1 @ start result
cmp r5,r1
 
bne 2f
ldrmov r5,[r4r1,#div_ident]0 @ loaddivision de r0,r1 par valuer2
bl division32R
add r6,r6,r5 @ and add
mov r6,r2 @ base <- remainder
2:
tst r5,#1 @ exposant even or odd
add r3,r3,#1
cmpbeq r3,r03f
bltumull 1br0,r1,r6,r3
mov r0r2,r6 @ return sumr4
bl division32R
100:
popmov {r1-r6r3,lr}r2 @ result <- @ restaur registersremainder
3:
bx lr @ return
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,r3
100: @ 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 number
1: @ 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 3f
2: @ 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 @ remainder
100: @ 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 item
1: @ 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 2
3: @ 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 loop
4: @ 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
/******************************************************************/
/* printdisplay heapdivisors function */
/******************************************************************/
/* r0 contains elementsaddress numberof divisors area */
/* r1 contains the flagnumber (0of area 1items or 2) */
displayDivisors:
/* r2 contains address of divisors area */
push {r2-r8,lr} @ save registers
printHeap:
cmp r1,#0
push {r0-r8,lr} @ save registers
movbeq r7,r0100f
mov r8r2,r1
mov r3,#0 @ indice
mov r4,r0
1:
lsladd r5,r4,r3,lsl #3 @ N° element * 82
ldr r0,[r5] @ load factor
add r4,r2
 
ldr r5,[r4,#div_flag]
cmpldr r5r1,r8iAdrsZoneConv
bl conversion10 @ call décimal conversion
bne 2f
ldr r0,[r4,#div_ident]iAdrszMessResultFact
ldr r1,iAdrsValue iAdrsZoneConv @ andinsert convertconversion asciiin stringmessage
bl conversion10strInsertAtCharInc
ldrbl affichageMess r0,iAdrszMessResult @ display result message
add r3,#1 @ other ithem
bl affichageMess
cmp r3,r2 @ items maxi ?
2:
add r3,r3,#1
cmp r3,r7
blt 1b
ldr r0,iAdrszCarriageReturn
bl affichageMess
b 100f
100:
pop {r0-r8,lr} @ restaur registers
bx lr @ return
/******************************************************************/
/* divisors function */
/******************************************************************/
/* r0 contains the number */
/* r1 contains address of divisors area
/* r0 return divisors number */
/* r1 return counter odd divisors */
divisors:
push {r2-r11,lr} @ save registers
cmp r0,#1 @ = 1 ?
movle r0,#0
ble 100f
mov r7,r0
mov r8,r1
mov r11,#1 @ counter odd divisors
mov r0,#1 @ first divisor = 1
str r0,[r8,#div_ident]
mov r0,#0
str r0,[r8,#div_flag]
tst r7,#1 @ number is odd ?
addne r11,#1
mov r0,r7 @ last divisor = N
add r10,r8,#8 @ store at next element
str r0,[r10,#div_ident]
mov r0,#0
str r0,[r10,#div_flag]
 
mov r6,#2 @ first divisor
mov r5,#2 @ Counter divisors
2: @ begin loop
mov r0,r7 @ dividende = number
mov r1,r6 @ divisor
bl division
cmp r3,#0 @ remainder = 0 ?
bne 3f
cmp r2,r6
blt 4f @ quot<divisor end
lsl r10,r5,#3 @ N° element * 8
add r10,r10,r8 @ and add at area begin address
str r2,[r10,#div_ident]
mov r0,#0
str r0,[r10,#div_flag]
add r5,r5,#1 @ increment counter
cmp r5,#NBDIVISORS @ area maxi ?
bge 99f
tst r2,#1
addne r11,#1 @ count odd divisors
cmp r2,r6 @ quotient = divisor ?
ble 4f
lsl r10,r5,#3 @ N° element * 8
add r10,r10,r8 @ and add at area begin address
str r6,[r10,#div_ident]
mov r0,#0
str r0,[r10,#div_flag]
add r5,r5,#1 @ increment counter
cmp r5,#NBDIVISORS @ area maxi ?
bge 99f
tst r6,#1
addne r11,#1 @ count odd divisors
3:
cmp r2,r6
ble 4f
add r6,r6,#1 @ increment divisor
b 2b @ and loop
 
4:
mov r0,r5 @ return divisors number
mov r1,r11 @ retourn count odd divisors
b 100f
99: @ error
ldr r0,iAdrszMessErrorArea
bl affichageMess
mov r0,#-1
100:
pop {r2-r11r8,lr} @ restaur registers
bx lr @ return
iAdrszMessResultFact: .int szMessResultFact
iAdrszMessListDivi: .int szMessListDivi
iAdrszMessErrorAreaiAdrsZoneConv: .int szMessErrorAreasZoneConv
/***************************************************/
/* ROUTINES INCLUDE */
/***************************************************/
.include "../affichage.inc"
</syntaxhighlight>
</lang>
{{Output}}
<pre>
Program start
Line 1,013 ⟶ 1,548:
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.
 
</pre>
 
=={{header|C#|C sharp}}==
=={{header|C sharp|C#}}==
{{trans|Go}}
<langsyntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Linq;
Line 1,113 ⟶ 1,655:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>The first 220 Zumkeller numbers are:
Line 1,142 ⟶ 1,684:
 
=={{header|C++}}==
<syntaxhighlight lang="cpp>#include <iostream">
<lang cpp>
#include <iostream>
#include <cmath>
#include <vector>
Line 1,152 ⟶ 1,693:
using namespace std;
 
//returns Returns n in binary right justified with length passed and padded with zeroes
const uint* binary(uint n, uint length);
//length passed and padded with zeroes
int* Bin(int n, int length);
 
//returns Returns the sum of the binary ordered subset of rank r.
// Adapted from Sympy impementationimplementation.
vector<int>uint subset_unrank_binsum_subset_unrank_bin(const vector<intuint>& d, intuint r);
 
vector <intuint> factors(intuint x);
 
bool isPrime(intuint number);
 
bool isZum(intuint 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<intuint> zumz;
for (uint n = 2; zumz.size() < 220; n++)
int n = 2;
if (isZum(n))
zumz.push_back(n);
cout << "The first 220 Zumkeller numbers:\n\n";
cout << zumz << endl << endl;
while (zumz.size() < 220)
{
if (isZum(n))
zumz.push_back(n);
n++;
}
for (int i = 0; i < zumz.size(); i++)
{
if (i % 10 == 0)
cout << endl;
cout << setw(10) << zumz[i] << ' ';
}
 
cout << "\n\nFirstFirst 40 odd Zumkeller numbers:\n\n" << endl;
vector<intuint> zumz2;
for (uint n = 2; zumz2.size() < 40; n++)
n = 2;
if (n % 2 && isZum(n))
while (zumz2.size() < 40)
zumz2.push_back(n);
{
cout << zumz2 << endl << endl;
if (n % 2 && isZum(n))
zumz2.push_back(n);
n++;
}
for (int i = 0; i < zumz2.size(); i++)
{
if (i % 10 == 0)
cout << endl;
cout << setw(10) << zumz2[i] << ' ';
}
cout << "\n\nFirst 40 odd Zumkeller numbers not ending in 5:\n\n";
vector<int> zumz3;
n = 2;
while (zumz3.size() < 40)
{
if (n % 2 && (n % 10) != 5 && isZum(n))
{
zumz3.push_back(n);
}
n++;
}
for (int i = 0; i < zumz3.size(); i++)
{
if (i % 10 == 0)
cout << endl;
cout << setw(10) << zumz3[i] << ' ';
}
 
cout << "First 40 odd Zumkeller numbers not ending in 5:" << endl;
return 0;
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 Returns n in binary right justified with length passed and padded with zeroes
const uint* binary(uint n, uint length) {
//length passed and padded with zeroes
uint* bin = new uint[length]; // array to hold result
int* Bin(int n, int length)
fill(bin, bin + length, 0); // fill with zeroes
{
// convert n to binary and store right justified in bin
int* bin, rem, i = 0;
for (uint i = 0; n > 0; i++) {
 
uint rem = n % 2;
bin = new int[length]; //array to hold result
n /= 2;
for (int i = 0; i < length; i++) //fill with zeroes
if (rem)
bin[i] = 0;
bin[length - 1 - i] = 1;
//convert n to binary and store right justified in bin
while (n > 0) }
{
rem = n % 2;
n = n / 2;
if (rem)
bin[length - 1 - i] = 1;
i++;
}
 
return bin;
}
 
//returns Returns the sum of the binary ordered subset of rank r.
// Adapted from Sympy impementationimplementation.
vector<int>uint subset_unrank_binsum_subset_unrank_bin(const vector<intuint>& d, intuint r) {
vector<uint> subset;
{
// convert r to binary array of same size as d
vector<int> subset;
const uint* bits = binary(r, d.size() - 1);
int* bits;
//convert r to binary array of same size as d
bits = Bin(r, d.size() - 1);
//get binary ordered subset
for (int i = 0; i < d.size() - 1; i++)
{
if (bits[i])
{
subset.push_back(d[i]);
}
}
 
return // 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 <intuint> factors(intuint 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)
vector <int> result;
result.push_back(x / i);
int i = 1;
}
// This will loop from 1 to int(sqrt(x))
}
while (i * i <= x) {
// Check if i divides x without leaving a remainder
if (x % i == 0) {
result.push_back(i);
 
// return the sorted factors of x
if (x / i != i)
sort(result.push_backbegin(x), / iresult.end());
return result;
}
i++;
}
// Return the list of factors of x
return result;
}
 
bool isPrime(intuint number) {
if (number < 2) return false;
{
if (number <== 2) return falsetrue;
if (number % 2 == 20) return truefalse;
for (uint i = 3; i * i <= number; i += 2)
if (number % 2 == 0) return false;
for (int i = 3; (i * i) <=if (number; % i +== 20) return false;
if (number % i == 0) return false;
 
return true;
}
 
bool isZum(intuint n) {
// if prime it ain't no zum
{
if (isPrime(n))
//if prime it ain't no zum
return false;
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
//get sum of divisors
if (s % 2 || s < 2 * n)
vector<int> d = factors(n);
return false;
sort(d.begin(), d.end());
int s = accumulate(d.begin(), d.end(), 0);
 
// if sumwe get here and n is odd or sumn <has 2*nat itleast ain24 divisors it'ts noa zum!
// Valid for even n < 99504. To test n beyond this bound, comment out this condition.
if (s % 2 || s < 2 * n)
// And wait all day. Thanks to User:Horsth for taking the time to find this bound!
return false;
if (n % 2 || d.size() >= 24)
return true;
 
if (!(s % 2) && d[d.size() - 1] <= s / 2)
//if we get here and n is odd or n has at least 24 divisors it's a zum!
for (uint x = 2; (uint) log2(x) < (d.size() - 1); x++) // using log2 prevents overflow
if (n % 2 || d.size() >= 24)
if (sum_subset_unrank_bin(d, x) == s / 2)
return true;
return true; // congratulations it's a zum num!!
 
// if we get here it ain't no zum
if (!(s % 2) && d[d.size() - 1] <= s / 2)
return false;
{
}</syntaxhighlight>
//using log2 prevents overflow
for (int x = 2; (int)log2(x) < (d.size() - 1); x++)
{
vector<int> I = subset_unrank_bin(d, x);
int sum = accumulate(I.begin(), I.end(), 0);
if (sum == s / 2) //congratulations it's a zum num!!
return true;
}
}
 
//if we get here it ain't no zum
return false;
}
 
</lang>
{{out}}
<pre>
The firstFirst 220 Zumkeller numbers:
 
6 12 20 24 28 30 40 42 48 54
 
6 56 12 60 20 66 24 70 28 78 30 80 40 84 42 88 48 90 54 96
56 102 60 104 66 108 70112 114 78 120 80 126 84 132 88 138 90 140 96
102 150 104 156 108 160 112 168 114 174 120 176 126 180 132 186 138 192 140 198
150 204 156 208 160 210 168 216 174 220 176 222 180 224 186 228 192 234 198 240
204 246 208 252 210 258 216 260 220 264 222 270 224 272 228 276 234 280 240 282
246 294 252 300 258 304 260 306 264 308 270 312 272 318 276 320 280 330 282 336
294 340 300 342 304 348 306 350 308 352 312 354 318 360 320 364 330 366 336 368
340 372 342 378 348 380 350 384 352 390 354 396 360 402 364 408 366 414 368 416
372 420 378 426 380 432 384 438 390 440 396 444 402 448 408 456 414 460 416 462
420 464 426 468 432 474 438 476 440 480 444 486 448 490 456 492 460 496 462 498
464 500 468 504 474 510 476 516 480 520 486 522 490 528 492 532 496 534 498 540
500 544 504 546 510 550 516 552 520 558 522 560 528 564 532 570 534 572 540 580
544 582 546 588 550 594 552 600 558 606 560 608 564 612 570 616 572 618 580 620
582 624 588 630 594 636 600 640 606 642 608 644 612 650 616 654 618 660 620 666
624 672 630 678 636 680 640 684 642 690 644 696 650 700 654 702 660 704 666 708
672 714 678 720 680 726 684 728 690 732 696 736 700 740 702 744 704 750 708 756
714 760 720 762 726 768 728 770 732 780 736 786 740 792 744 798 750 804 756 810
760 812 762 816 768 820 770 822 780 828 786 832 792 834 798 836 804 840 810 852
812 858 816 860 820 864 822 868 828 870 832 876 834 880 836 888 840 894 852 896
858 906 860 910 864 912 868 918 870 920 876 924 880 928 888 930 894 936 896 940
906 942 910 945 912 948 918 952 920 960 924 966 928 972 930 978 936 980 940 984
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
 
945 6435 1575 6615 2205 6825 2835 7245 3465 7425 4095 7875 4725 8085 5355 8415 5775 8505 5985 8925
6435 9135 6615 9555 6825 9765 7245 10395 7425 11655 7875 12285 808512705 12915 8415 13545 8505 14175 8925
9135 14805 9555 15015 9765 15435 10395 16065 11655 16695 12285 17325 12705 17955 12915 18585 13545 19215 14175 19305
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
 
81081 351351 153153 459459 171171 513513 189189 567567 207207 621621 223839 671517 243243 729729 261261 742203 279279 783783 297297 793611
351351 812889 459459 837837 513513 891891 567567 908523 621621 960687 671517 999999 729729 1024947 742203 1054053 7837831072071 1073709 793611
812889 1095633 837837 1108107 8918911145529 1162161 908523 1198197 960687 1224531 999999 1270269 1024947 1307691 1054053 1324323 1072071 10737091378377
1095633 1108107 1145529 1162161 1198197 1224531 1270269 1307691 1324323 1378377
*/
</pre>
 
=={{header|D}}==
{{trans|C#}}
<langsyntaxhighlight lang="d">import std.algorithm;
import std.stdio;
 
Line 1,470 ⟶ 1,961:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>The first 220 Zumkeller numbers are:
Line 1,497 ⟶ 1,988:
960687 999999 1024947 1054053 1072071 1073709 1095633 1108107
1145529 1162161 1198197 1224531 1270269 1307691 1324323 1378377</pre>
 
=={{header|EasyLang}}==
<syntaxhighlight>
proc divisors n . divs[] .
divs[] = [ 1 n ]
for i = 2 to sqrt n
if n mod i = 0
j = n / i
divs[] &= i
if i <> j
divs[] &= j
.
.
.
.
func ispartsum divs[] sum .
if sum = 0
return 1
.
if len divs[] = 0
return 0
.
last = divs[len divs[]]
len divs[] -1
if last > sum
return ispartsum divs[] sum
.
if ispartsum divs[] sum = 1
return 1
.
return ispartsum divs[] (sum - last)
.
func iszumkeller n .
divisors n divs[]
for v in divs[]
sum += v
.
if sum mod 2 = 1
return 0
.
if n mod 2 = 1
abund = sum - 2 * n
return if abund > 0 and abund mod 2 = 0
.
return ispartsum divs[] (sum / 2)
.
#
print "The first 220 Zumkeller numbers are:"
i = 2
repeat
if iszumkeller i = 1
write i & " "
count += 1
.
until count = 220
i += 1
.
print "\n\nThe first 40 odd Zumkeller numbers are:"
count = 0
i = 3
repeat
if iszumkeller i = 1
write i & " "
count += 1
.
until count = 40
i += 2
.
</syntaxhighlight>
 
{{out}}
<pre>
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
</pre>
 
=={{header|F_Sharp|F#}}==
This task uses [https://rosettacode.org/wiki/Sum_of_divisors#F.23]
<syntaxhighlight lang="fsharp">
// Zumkeller numbers: Nigel Galloway. May 16th., 2021
let rec fG n g=match g with h::_ when h>=n->h=n |h::t->fG n t || fG(n-h) t |_->false
let 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
|_->false
Seq.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"
</syntaxhighlight>
{{out}}
<pre>
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
</pre>
 
=={{header|Factor}}==
{{works with|Factor|0.99 2019-10-06}}
<langsyntaxhighlight lang="factor">USING: combinators grouping io kernel lists lists.lazy math
math.primes.factors memoize prettyprint sequences ;
 
Line 1,541 ⟶ 2,133:
 
"First 40 odd Zumkeller numbers not ending with 5:" print
40 odd-zumkellers-no-5 8 show</langsyntaxhighlight>
{{out}}
<pre>
Line 1,572 ⟶ 2,164:
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 1,662 ⟶ 2,254:
}
fmt.Println()
}</langsyntaxhighlight>
 
{{out}}
Line 1,693 ⟶ 2,285:
</pre>
 
=={{header|Haskell}}==
{{Trans|Python}}
<syntaxhighlight lang="haskell">import Data.List (group, sort)
import Data.List.Split (chunksOf)
import Data.Numbers.Primes (primeFactors)
 
-------------------- ZUMKELLER NUMBERS -------------------
 
isZumkeller :: Int -> Bool
isZumkeller 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] -> Bool
summable _ [] = False
summable 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] ->
String
tabulated 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 -> String
justifyRight n c = (drop . length) <*> (replicate n c <>)</syntaxhighlight>
{{Out}}
<pre>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</pre>
 
=={{header|J}}==
Implementation:<syntaxhighlight lang="J>divisors=: {{ \:~ */@>,{ (^ i.@>:)&.">/ __ q: y }}
zum=: {{
if. 2|s=. +/divs=. divisors y do. 0
elseif. 2|y do. (0<k) * 0=2|k=. s-2*y
else. s=. -:s for_d. divs do. if. d<:s do. s=. s-d end. end. s=0
end.
}}@></syntaxhighlight>
 
Task examples:<syntaxhighlight lang="J"> 10 22$1+I.zum 1+i.1000 NB. 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
4 10$1+2*I.zum 1+2*i.1e4 NB. 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
4 10$(#~ 0~:5|])1+2*I.zum 1+2*i.1e6 NB. 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</syntaxhighlight>
=={{header|Java}}==
<langsyntaxhighlight lang="java">
import java.util.ArrayList;
import java.util.Collections;
Line 1,807 ⟶ 2,535:
 
}
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,836 ⟶ 2,564:
1095633 1108107 1145529 1162161 1198197 1224531 1270269 1307691 1324323 1378377
</pre>
 
=={{header|jq}}==
{{Works with|jq|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.
<syntaxhighlight lang="jq"># The factors, sorted
def 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;</syntaxhighlight><syntaxhighlight lang="jq">## The tasks:
 
"First 220:", limit(220; range(2; infinite) | select(is_zumkeller)),
""
"First 40 odd:", limit(40; range(3; infinite; 2) | select(is_zumkeller))</syntaxhighlight>
{{out}}
<pre>
First 220:
6
12
20
24
28
...
984
 
First 40 odd:
945
1575
2205
2835
3465
...
19305</pre>
 
=={{header|Julia}}==
<langsyntaxhighlight lang="julia">using Primes
 
function factorize(n)
Line 1,886 ⟶ 2,716:
println("\n\nFirst 40 odd Zumkeller numbers not ending with 5:")
printconditionalnum((n) -> isodd(n) && (string(n)[end] != '5') && iszumkeller(n), 40, 8)
</langsyntaxhighlight>{{out}}
<pre>
First 220 Zumkeller numbers:
Line 1,920 ⟶ 2,750:
=={{header|Kotlin}}==
{{trans|Java}}
<langsyntaxhighlight lang="scala">import java.util.ArrayList
import kotlin.math.sqrt
 
Line 2,028 ⟶ 2,858:
return divisors
}
}</langsyntaxhighlight>
{{out}}
<pre>First 220 Zumkeller numbers:
Line 2,056 ⟶ 2,886:
 
=={{header|Lobster}}==
<langsyntaxhighlight lang="Lobster">import std
 
// Derived from Julia and Python versions
Line 2,116 ⟶ 2,946:
print "\n\n40 odd Zumkeller numbers:"
printZumkellers(40, true)
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,149 ⟶ 2,979:
9135 9555 9765 10395 11655 12285 12705 12915 13545 14175
14805 15015 15435 16065 16695 17325 17955 18585 19215 19305
</pre>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<syntaxhighlight lang="Mathematica">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</syntaxhighlight>
{{out}}
<pre>{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}</pre>
 
=={{header|Nim}}==
{{trans|Go}}
<syntaxhighlight lang="Nim">import math, strutils
 
template isEven(n: int): bool = (n and 1) == 0
template 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</syntaxhighlight>
 
{{out}}
<pre>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</pre>
 
=={{header|PARI/GP}}==
{{trans|Mathematica_/_Wolfram_Language}}
<syntaxhighlight lang="PARI/GP">
\\ Define a function to check if a number is Zumkeller
isZumkeller(n) = {
my(d = divisors(n));
my(ds = sum(i=1, #d, d[i])); \\ Total of divisors
if (ds % 2, return(0)); \\ If sum of divisors is odd, return false
my(coeffs = vector(ds+1, i, 0)); \\ Create a vector to store coefficients
coeffs[1] = 1;
for(i=1, #d, coeffs = Pol(coeffs) * (1 + x^d[i]); coeffs = Vecrev(coeffs); if(#coeffs > ds + 1, coeffs = coeffs[^1])); \\ Generate coefficients
coeffs[ds \ 2 + 1] > 0; \\ Check if the middle coefficient is positive
}
 
\\ Generate a list of Zumkeller numbers
ZumkellerList(limit) = {
my(res = List(), i = 1);
while(#res < limit,
if(isZumkeller(i), listput(res, i));
i++;
);
Vec(res); \\ Convert list to vector
}
 
\\ Generate a list of odd Zumkeller numbers
OddZumkellerList(limit) = {
my(res = List(), i = 1);
while(#res < limit,
if(isZumkeller(i), listput(res, i));
i += 2; \\ Only check odd numbers
);
Vec(res); \\ Convert list to vector
}
 
\\ Call the functions to get the lists
zumkeller220 = ZumkellerList(220);
oddZumkeller40 = OddZumkellerList(40);
 
\\ Print the results
print(zumkeller220);
print(oddZumkeller40);
</syntaxhighlight>
 
{{out}}
<pre>
[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]
</pre>
 
=={{header|Pascal}}==
Using sieve for primedecomposition<BR>
Now using the trick, that one partition sum must include n and improved recursive search.<BR>
Limit is ~1.2e11
<syntaxhighlight lang="pascal">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 decomposition
const
//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 DIVS
type
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 decomposition
procedure InitSmallPrimes;
//only odd numbers
const
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 base
var
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 Global
begin
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.
</syntaxhighlight>
{{out}}
<pre>
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<
</pre>
 
=={{header|Perl}}==
{{libheader|ntheory}}
<langsyntaxhighlight lang="perl">use strict;
use warnings;
use feature 'say';
Line 2,197 ⟶ 3,982:
$n = 0; $z = '';
$z .= do { $n < 40 ? (!!($_%2 and $_%5) and is_Zumkeller($_) and ++$n and "$_ ") : last } for 1 .. Inf;
in_columns(10, $z);</langsyntaxhighlight>
 
{{out}}
Line 2,224 ⟶ 4,009:
812889 837837 891891 908523 960687 999999 1024947 1054053 1072071 1073709
1095633 1108107 1145529 1162161 1198197 1224531 1270269 1307691 1324323 1378377</pre>
 
=={{header|Perl 6}}==
{{works with|Rakudo|2019.07.1}}
 
<lang perl6>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";</lang>
{{out}}
<pre>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</pre>
 
=={{header|Phix}}==
{{trans|Go}}
<!--(phixonline)-->
<lang Phix>function isPartSum(sequence f, integer l, t)
<syntaxhighlight lang="Phix">
with javascript_semantics
function isPartSum(sequence f, integer l, t)
if t=0 then return true end if
if l=0 then return false end if
Line 2,300 ⟶ 4,027:
integer t = sum(f)
-- an odd sum cannot be split into two equal sums
if remainderodd(t,2)=1 then return false end if
-- if n is odd use 'abundant odd number' optimization
if remainderodd(n,2)=1 then
integer abundance := t - 2*n
return abundance>0 and remaindereven(abundance,2)=0
end if
-- if n and t both even check for any partition of t/2
Line 2,310 ⟶ 4,037:
end function
sequence tests = {{220,1,0,20,"%3d %n"},
{40,2,0,10,"%5d %n"},
{40,2,5,8,"%7d %n"}}
integer lim, step, rem, cr; string fmt
for t=1 to length(tests) do
{lim, step, rem, cr, fmt} = tests[t]
string oddo = iff(step=1?"":"odd "),
wchw = iff(rem=0?"":"which don't end in 5 ")
printf(1,"The first %d %sZumkeller numbers %sare:\n",{lim,oddo,wchw})
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 printf(1,fmt,{i,remainder(count,cr)=0 then puts(1,"\n"}) end if
end if
i += step
end while
printf(1,"\n")
end for</lang>
</syntaxhighlight>
{{out}}
<pre>
Line 2,367 ⟶ 4,094:
 
=={{header|PicoLisp}}==
<langsyntaxhighlight lang="PicoLisp">(de propdiv (N)
(make
(for I N
Line 2,418 ⟶ 4,145:
(and
(=0 (% C 8))
(prinl) ) ) )</langsyntaxhighlight>
{{out}}
<pre>
Line 2,449 ⟶ 4,176:
===Procedural===
Modified from a footnote at OEIS A083207 (see reference in problem text) by Charles R Greathouse IV.
<langsyntaxhighlight lang="python">from sympy import divisors
 
from sympy.combinatorics.subsets import Subset
Line 2,481 ⟶ 4,208:
print("\n\n40 odd Zumkeller numbers:")
printZumkellers(40, True)
</langsyntaxhighlight>{{out}}
<pre>
220 Zumkeller numbers:
Line 2,519 ⟶ 4,246:
Relying on the standard Python libraries, as an alternative to importing SymPy:
 
<langsyntaxhighlight lang="python">'''Zumkeller numbers'''
 
from itertools import accumulate, chain, count, groupby, islice, product(
accumulate, chain, count, groupby, islice, product
)
from functools import reduce
from math import floor, sqrt
fromimport operator import mul
 
 
# ------------------------ ZUMKELLER- -----------------------
 
# isZumkeller :: Int -> Bool
def isZumkeller(n):
'''True if there exists a disjoint partition of the
of the divisors of m, such that the two sets have the same sum.
the same sum.
(In other words, if n is in OEIS A083207)
'''
Line 2,540 ⟶ 4,270:
half = m // 2
return half in ds or (
all(map(lambda x: ge(half >= x), ds)) and (
summable(half)(, ds)
)
)
Line 2,549 ⟶ 4,279:
 
# summable :: Int -> [Int] -> Bool
def summable(x, xs):
'''True if any subset of the sorted
list xs sums to x.
'''
defif go(y, ys)xs:
if ysx in xs:
ifreturn y in ys:True
return True
else:
d = y - ys[0]
return (0 < d and go(d, ys[1:])) or go(y, ys[1:])
else:
returnt False= xs[1:]
return lambdasummable(x - xs:[0], got) or summable(x, xst)
else:
return False
 
 
# -------------------------- TEST-- -------------------------
# main :: IO ()
def main():
'''First 220 Zumkeller numbers, and first 40 odd Zumkellers.'''
and first 40 odd Zumkellers.
'''
 
tenColumns = tabulated(10)
Line 2,586 ⟶ 4,316:
 
 
# ----------------------- TABULATION-- ----------------------
 
# tabulated :: Int -> [a] -> String
Line 2,602 ⟶ 4,332:
])
])
return lambda xs: go(xs)
 
 
# ------------------------- GENERIC- ------------------------
 
# chunksOf :: Int -> [a] -> [[a]]
Line 2,613 ⟶ 4,343:
divible, the final list will be shorter than n.
'''
return lambdadef go(xs): reduce(
lambdareturn a, i: a + [xs[i:n + i]],(
xs[i:n + i] for i in range(0, len(xs), n), []
) if 0 < n else []None
return go
 
 
# concatMap :: (a -> [b]) -> [a] -> [b]
def concatMap(f):
'''A concatenated list or string over which a function f
has been mapped.
The list monad can be derived by using an (a -> [b])
function which wraps its output in a list (using an
empty list to represent computational failure).
'''
return lambda xs: chain.from_iterable(map(f, xs))
 
 
Line 2,637 ⟶ 4,357:
return [a * b for a, b in product(
a,
accumulate(chain([1], x), operator.mul)
)]
return sorted(
Line 2,661 ⟶ 4,381:
'''
return 0 == x % 2
 
 
# ge :: Eq a => a -> a -> Bool
def ge(a):
def go(b):
return operator.ge(a, b)
return go
 
 
Line 2,695 ⟶ 4,422:
or xs itself if n > length xs.
'''
return lambdadef go(xs): (
xs[0:return n](
if isinstance(xs, (list, tuple)) xs[0:n]
else list(islice if isinstance(xs, n(list, tuple))
else list(islice(xs, n))
)
)
return go
 
 
Line 2,707 ⟶ 4,436:
The initial seed value is x.
'''
def go(f, x):
v =def g(x):
while not p( v): = x
vwhile =not fp(v):
return v = f(v)
return lambda f: lambda x: go(f, x) return v
return g
return go
 
 
# MAIN ---
if __name__ == '__main__':
main()</langsyntaxhighlight>
{{Out}}
<pre>First 220 Zumkeller numbers:
Line 2,754 ⟶ 4,485:
{{trans|Zkl}}
 
<langsyntaxhighlight lang="racket">#lang racket
 
(require math/number-theory)
Line 2,794 ⟶ 4,525:
(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)))))</langsyntaxhighlight>
 
{{out}}
Line 2,814 ⟶ 4,545:
729729 742203 783783 793611 812889 837837 891891 908523 960687 999999 1024947 1054053 1072071 1073709 1095633 1108107
1145529 1162161 1198197 1224531 1270269 1307691 1324323 1378377</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
{{libheader|ntheory}}
<syntaxhighlight lang="raku" line>use ntheory:from<Perl5> <factor is_prime>;
 
sub zumkeller ($range) {
$range.grep: -> $maybe {
next if $maybe < 3 or $maybe.&is_prime;
my @divisors = $maybe.&factor.combinations».reduce( &[×] ).unique.reverse;
next unless [and] @divisors > 2, @divisors %% 2, (my $sum = @divisors.sum) %% 2, ($sum /= 2) ≥ $maybe;
my $zumkeller = False;
if $maybe % 2 {
$zumkeller = True
} else {
TEST: for 1 ..^ @divisors/2 -> $c {
@divisors.combinations($c).map: -> $d {
next if $d.sum != $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";</syntaxhighlight>
{{out}}
<pre>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</pre>
 
=={{header|REXX}}==
The construction of the partitions were created in the order in which the most likely partitions would match.
<langsyntaxhighlight lang="rexx">/*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.*/
Line 2,828 ⟶ 4,619:
#= 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*/
Line 2,838 ⟶ 4,629:
#= 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*/
Line 2,848 ⟶ 4,639:
#= 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*/
Line 2,860 ⟶ 4,651:
say strip($, 'L'); $= j; return /*say, add*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
PDaSiSqrt: procedure; parse arg x; 1 zr= 1 b0; oddq= x//21; /*get X & Z & B (the 1st argument). 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= 0;iSqrt(x) q= 1 /*calculate [↓] ══integerinteger square root══ root of ___X. */
do while q<=z; q=q*4; end /*R: an integer which will be √ X */
do while q>1; q=q%4; _= z-r-q; r=r%2; if _>=0 then do; z=_; r=r+q; end
end /*while q>1*/ /* [↑] compute the integer sqrt 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*/
Line 2,891 ⟶ 4,683:
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. */
Line 2,901 ⟶ 4,693:
_= 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*/</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default inputs:}}
<pre>
══════════════════════════════════════════════ The first 220 Zumkeller numbers are: ═══════════════════════════════════════════════
═════════════════════════════ 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
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
264 270 272 276 280 282 294 300 304 306 308 312 318 320 330 336 340 342 348 350 352 354 360 364
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
366 368 372 378 380 384 390 396 402 408 414 416 420 426 432 438 440 444 448 456 460 462 464 468
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
474 476 480 486 490 492 496 498 500 504 510 516 520 522 528 532 534 540 544 546 550 552 558 560
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
564 570 572 580 582 588 594 600 606 608 612 616 618 620 624 630 636 640 642 644 650 654 660 666
918 920 924 928 930 936 940 942 945 948 952 960 966 972 978 980 984
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: ═════════════════════════════════════════════
════════════════════════════ 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
9135 9555 9765 10395 11655 12285 12705 12915 13545 14175 14805 15015 15435 16065 16695 17325 17955 18585 19215 19305
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
621621 671517 729729 742203 783783 793611 812889 837837 891891 908523 960687 999999 1024947 1054053 1072071 1073709 1095633 1108107 1145529 1162161 1198197 1224531
1054053 1072071 1073709 1095633 1108107 1145529 1162161 1198197 1224531 1270269 1307691 1324323 1378377
</pre>
1378377
 
=={{header|Ring}}==
<syntaxhighlight lang="ring">
load "stdlib.ring"
 
see "working..." + nl
see "The first 220 Zumkeller numbers are:" + nl
 
permut = []
zumind = []
zumodd = []
limit = 19305
num1 = 0
num2 = 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:" + nl
for n = 1 to len(zumodd)
if (n-1)%8 = 0
see nl + " " + zumodd[n]
else
see " " + zumodd[n]
ok
next
 
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
</syntaxhighlight>
Output:
<pre>
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...
</pre>
 
=={{header|Ruby}}==
<syntaxhighlight lang="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)
</syntaxhighlight>
{{out}}
<pre>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
</pre>
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">
use std::convert::TryInto;
 
/// Gets all divisors of a number, including itself
fn 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 value
fn 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;
}
}
</syntaxhighlight>
{{out}}
<pre>
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
</pre>
 
=={{header|Sidef}}==
<langsyntaxhighlight lang="ruby">func is_Zumkeller(n) {
 
return false if n.is_prime
Line 2,966 ⟶ 5,118:
 
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(' '))</langsyntaxhighlight>
{{out}}
<pre>
Line 2,978 ⟶ 5,130:
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
</pre>
 
=={{header|Standard ML}}==
<syntaxhighlight lang="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;
</syntaxhighlight>
call loop and output - interpreter
<syntaxhighlight lang="Standard ML">
- 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
</syntaxhighlight>
 
=={{header|Swift}}==
Line 2,983 ⟶ 5,226:
{{trans|Go}}
 
<langsyntaxhighlight lang="swift">import Foundation
 
extension BinaryInteger {
Line 3,043 ⟶ 5,286:
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)))")</langsyntaxhighlight>
 
{{out}}
Line 3,050 ⟶ 5,293:
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]</pre>
 
=={{header|Typescript}}==
{{trans|Go}}
<syntaxhighlight lang="typescript">
/**
* return an array of divisors of a number(n)
* @params {number} n The number to find divisors from
* @return {number[]} divisors of n
*/
function getDivisors(n: number): number[] {
//initialize divisors array
let divisors: number[] = [1, n]
//loop through all numbers from 2 to sqrt(n)
for (let i = 2; i*i <= n; i++) {
// if i is a divisor of n
if (n % i == 0) {
// add i to divisors array
divisors.push(i);
// quotient of n/i is also a divisor of n
let j = n/i;
// if quotient is not equal to i
if (i != j) {
// add quotient to divisors array
divisors.push(j);
}
}
}
 
return divisors
}
/**
* return sum of an array of number
* @param {number[]} arr The array we need to sum
* @return {number} sum of arr
*/
function getSum(arr: number[]): number {
return arr.reduce((prev, curr) => prev + curr, 0)
}
/**
* check if there is a subset of divisors which sums to a specific number
* @param {number[]} divs The array of divisors
* @param {number} sum The number to check if there's a subset of divisors which sums to it
* @return {boolean} true if sum is 0, false if divisors length is 0
*/
function isPartSum(divs: number[], sum: number): boolean {
// if sum is 0, the partition is sum up to the number(sum)
if (sum == 0) return true;
//get length of divisors array
let len = divs.length;
// if divisors array is empty the partion doesnt not sum up to the number(sum)
if (len == 0) return false;
//get last element of divisors array
let last = divs[len - 1];
//create a copy of divisors array without the last element
const newDivs = [...divs];
newDivs.pop();
// if last element is greater than sum
if (last > sum) {
// recursively check if there's a subset of divisors which sums to sum using the new divisors array
return isPartSum(newDivs, sum);
}
// recursively check if there's a subset of divisors which sums to sum using the new divisors array
// or if there's a subset of divisors which sums to sum - last using the new divisors array
return isPartSum(newDivs, sum) || isPartSum(newDivs, sum - last);
}
/**
* check if a number is a Zumkeller number
* @param {number} n The number to check if it's a Zumkeller number
* @returns {boolean} true if n is a Zumkeller number, false otherwise
*/
function isZumkeller(n: number): boolean {
// get divisors of n
let divs = getDivisors(n);
// get sum of divisors of n
let sum = getSum(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) {
let 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);
}
/**
* find x zumkeller numbers
* @param {number} x The number of zumkeller numbers to find
* @returns {number[]} array of x zumkeller numbers
*/
function getXZumkelers(x: number): number[] {
let zumkellers: number[] = [];
let i = 2;
let count= 0;
while (count < x) {
if (isZumkeller(i)) {
zumkellers.push(i);
count++;
}
i++;
}
 
return zumkellers;
}
 
/**
* find x Odd Zumkeller numbers
* @param {number} x The number of odd zumkeller numbers to find
* @returns {number[]} array of x odd zumkeller numbers
*/
function getXOddZumkelers(x: number): number[] {
let oddZumkellers: number[] = [];
let i = 3;
let count = 0;
while (count < x) {
if (isZumkeller(i)) {
oddZumkellers.push(i);
count++;
}
i += 2;
}
 
return oddZumkellers;
}
 
/**
* find x odd zumkeller number which are not end with 5
* @param {number} x The number of odd zumkeller numbers to find
* @returns {number[]} array of x odd zumkeller numbers
*/
function getXOddZumkellersNotEndWith5(x: number): number[] {
let oddZumkellers: number[] = [];
let i = 3;
let count = 0;
while (count < x) {
if (isZumkeller(i) && i % 10 != 5) {
oddZumkellers.push(i);
count++;
}
i += 2;
}
 
return oddZumkellers;
}
 
//get the first 220 zumkeller numbers
console.log("First 220 Zumkeller numbers: ", getXZumkelers(220));
 
//get the first 40 odd zumkeller numbers
console.log("First 40 odd Zumkeller numbers: ", getXOddZumkelers(40));
 
//get the first 40 odd zumkeller numbers which are not end with 5
console.log("First 40 odd Zumkeller numbers which are not end with 5: ", getXOddZumkellersNotEndWith5(40));
</syntaxhighlight>
 
{{out}}
<pre>
"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 which are not end 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]
</pre>
 
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<syntaxhighlight lang="vbnet">Module Module1
Function GetDivisors(n As Integer) As List(Of Integer)
Dim divs As New List(Of Integer) From {
1, n
}
Dim i = 2
While i * i <= n
If n Mod i = 0 Then
Dim j = n \ i
divs.Add(i)
If i <> j Then
divs.Add(j)
End If
End If
i += 1
End While
Return divs
End Function
 
Function IsPartSum(divs As List(Of Integer), sum As Integer) As Boolean
If sum = 0 Then
Return True
End If
Dim le = divs.Count
If le = 0 Then
Return False
End If
Dim last = divs(le - 1)
Dim newDivs As New List(Of Integer)
For i = 1 To le - 1
newDivs.Add(divs(i - 1))
Next
If last > sum Then
Return IsPartSum(newDivs, sum)
End If
Return IsPartSum(newDivs, sum) OrElse IsPartSum(newDivs, sum - last)
End Function
 
Function IsZumkeller(n As Integer) As Boolean
Dim divs = GetDivisors(n)
Dim sum = divs.Sum()
REM if sum is odd can't be split into two partitions with equal sums
If sum Mod 2 = 1 Then
Return False
End If
REM if n is odd use 'abundant odd number' optimization
If n Mod 2 = 1 Then
Dim abundance = sum - 2 * n
Return abundance > 0 AndAlso abundance Mod 2 = 0
End If
REM if n and sum are both even check if there's a partition which totals sum / 2
Return IsPartSum(divs, sum \ 2)
End Function
 
Sub Main()
Console.WriteLine("The first 220 Zumkeller numbers are:")
Dim i = 2
Dim count = 0
While count < 220
If IsZumkeller(i) Then
Console.Write("{0,3} ", i)
count += 1
If count Mod 20 = 0 Then
Console.WriteLine()
End If
End If
i += 1
End While
Console.WriteLine()
 
Console.WriteLine("The first 40 odd Zumkeller numbers are:")
i = 3
count = 0
While count < 40
If IsZumkeller(i) Then
Console.Write("{0,5} ", i)
count += 1
If count Mod 10 = 0 Then
Console.WriteLine()
End If
End If
i += 2
End While
Console.WriteLine()
 
Console.WriteLine("The first 40 odd Zumkeller numbers which don't end in 5 are:")
i = 3
count = 0
While count < 40
If i Mod 10 <> 5 AndAlso IsZumkeller(i) Then
Console.Write("{0,7} ", i)
count += 1
If count Mod 8 = 0 Then
Console.WriteLine()
End If
End If
i += 2
End While
End Sub
End Module</syntaxhighlight>
{{out}}
<pre>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</pre>
 
=={{header|V (Vlang)}}==
{{trans|Go}}
<syntaxhighlight lang="v (vlang)">fn get_divisors(n int) []int {
mut divs := [1, n]
for i := 2; i*i <= n; i++ {
if n%i == 0 {
j := n / i
divs << i
if i != j {
divs << j
}
}
}
return divs
}
fn sum(divs []int) int {
mut sum := 0
for div in divs {
sum += div
}
return sum
}
fn is_part_sum(d []int, sum int) bool {
mut divs := d.clone()
if sum == 0 {
return true
}
le := divs.len
if le == 0 {
return false
}
last := divs[le-1]
divs = divs[0 .. le-1]
if last > sum {
return is_part_sum(divs, sum)
}
return is_part_sum(divs, sum) || is_part_sum(divs, sum-last)
}
fn is_zumkeller(n int) bool {
divs := get_divisors(n)
s := sum(divs)
// if sum is odd can't be split into two partitions with equal sums
if s%2 == 1 {
return false
}
// if n is odd use 'abundant odd number' optimization
if n%2 == 1 {
abundance := s - 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 is_part_sum(divs, s/2)
}
fn main() {
println("The first 220 Zumkeller numbers are:")
for i, count := 2, 0; count < 220; i++ {
if is_zumkeller(i) {
print("${i:3} ")
count++
if count%20 == 0 {
println('')
}
}
}
println("\nThe first 40 odd Zumkeller numbers are:")
for i, count := 3, 0; count < 40; i += 2 {
if is_zumkeller(i) {
print("${i:5} ")
count++
if count%10 == 0 {
println('')
}
}
}
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) && is_zumkeller(i) {
print("${i:7} ")
count++
if count%8 == 0 {
println('')
}
}
}
println('')
}</syntaxhighlight>
 
{{out}}
<pre>
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
</pre>
 
=={{header|Wren}}==
{{trans|Go}}
{{libheader|Wren-math}}
{{libheader|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.
<syntaxhighlight lang="wren">import "./math" for Int, Nums
import "./fmt" for Fmt
import "io" for Stdout
 
var isPartSum // recursive
isPartSum = 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 = 0
var i = 2
while (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 = 0
i = 3
while (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 = 0
i = 3
while (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()</syntaxhighlight>
 
{{out}}
<pre>
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
</pre>
 
=={{header|zkl}}==
{{trans|Julia}} {{trans|Go}}
<langsyntaxhighlight lang="zkl">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 }) )
Line 3,076 ⟶ 5,836:
}
canSum(sum/2,ds) and n or Void.Skip // sum is even
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">println("First 220 Zumkeller numbers:");
zw:=[2..].tweak(isZumkellerW);
do(11){ zw.walk(20).pump(String,"%4d ".fmt).println() }
Line 3,087 ⟶ 5,847:
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() }</langsyntaxhighlight>
{{out}}
<pre style="font-size:83%">
Line 3,116 ⟶ 5,876:
1145529 1162161 1198197 1224531 1270269 1307691 1324323 1378377
</pre>
[[Link title]]
2,083

edits