Zumkeller numbers: Difference between revisions

m
m (→‎{{header|Pascal}}: too much copy and paste...)
 
(45 intermediate revisions by 21 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 33:
:* '''[[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 550 ⟶ 659:
 
=={{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.
This takes about 0.38 seconds to execute the two main searches — then a further 109 for the stretch goal!
 
<langsyntaxhighlight lang="applescript">on-- Sum properDivisors(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 {}
Line 574 ⟶ 701:
end properDivisors
 
-- Does a subset of the given list of numbers add up to the target value?
on canSumTo(lst, target)
on subsetOf:numberList sumsTo:target
script o
property llst : lstnumberList
property someNegatives : false
on cstssp(target, i)
repeat while (i > 1)
set n to item i of my llst
if (n = target) then return true
if (i = 1) then return false
set i to i - 1
if ((n = target) or (((n < target) or (someNegatives)) and (cstssp(target - n, i)))) then return true
end repeat
return (target = beginning of my lst)
end cs
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 cstssp(target, count o's llst)
end subsetOf:sumsTo:
end canSumTo
 
-- 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
script o
-- either n is odd or a subset of its proper divisors sums to half the sum of the divisors and it.
property divisors : properDivisors(n)
-- Using aliquotSum() to get the divisor sum and then calling properDivisors() too if a list's actually
end script
-- 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 ¬
repeat with thisDivisor in o's divisors
((n mod 2 = 1) or (my subsetOf:(properDivisors(n)) sumsTo:((sum + n) div 2))))
set sum to sum + thisDivisor
end repeat
set halfSum to sum / 2
return ((halfSum ≥ n) and (halfSum as integer = halfSum) and (canSumTo(o's divisors, halfSum)))
end isZumkeller
 
-- Task code:
-- Find and return q Zumkeller numbers, starting the search at n and continuing at the
on zumkellerNumbers(target, n, interval, filter)
-- Params:given how many requiredinterval, firstapplying numberthe toZumkeller test, intervalonly betweento numbers tested,passing the given filter.
on zumkellerNumbers(q, n, interval, filter)
-- script object imposing any further restrictions on the numbers.
script o
property zumkellers : {}
Line 615 ⟶ 747:
set counter to 0
repeat until (counter = targetq)
if ((filter's OK(n)) and (isZumkeller(n))) then
set end of o's zumkellers to n
Line 626 ⟶ 758:
end zumkellerNumbers
 
on joinText(textList, delimiter)
on format(resultList, heading, resultsPerLine, separator)
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
Line 632 ⟶ 773:
end script
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to separator
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) as text
end repeat
set AppleScript's text item delimiters to linefeed
set output toreturn joinText(o's output, as textlinefeed)
end formatForDisplay
set AppleScript's text item delimiters to astid
return output
end format
 
on doTask(cheating)
set output to {}
script defaultnoFilter
on OK(n)
return true
Line 654 ⟶ 791:
end script
set header to "1st 220 Zumkeller numbers:"
set end of output to formatformatForDisplay(zumkellerNumbers(220, 1, 1, defaultnoFilter), header, 20, " ")
set header to "1st 40 odd Zumkeller numbers:"
set end of output to formatformatForDisplay(zumkellerNumbers(40, 1, 2, defaultnoFilter), header, 10, " ")
-- Stretch goal:
set header to "1st 40 odd Zumkeller numbers not ending with 5:"
script notDivisibleBy5no5Multiples
on OK(n)
return (n mod 5 > 0)
end OK
end script
if (cheating) then
set end of output to format(zumkellerNumbers(40, 1, 2, notDivisibleBy5), header, 10, " ")
-- Knowing that the HCF of the first 203 odd Zumkellers not ending with 5
set astid to AppleScript's text item delimiters
-- is 63, just check 63 and each 126th number thereafter.
set AppleScript's text item delimiters to linefeed & linefeed
-- For the 204th - 907th such numbers, the HCF reduces to 21, so adjust accordingly.
set output to output as text
-- (See Horsth's comments on the Talk page.)
set AppleScript's text item delimiters to astid
set zumkellers to zumkellerNumbers(40, 63, 126, no5Multiples)
return output
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
doTask()</lang>
set cheating to false
doTask(cheating)</syntaxhighlight>
 
{{output}}
<langsyntaxhighlight 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
Line 697 ⟶ 845:
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"</langsyntaxhighlight>
 
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi}}
<langsyntaxhighlight lang="ARM Assembly">
/* ARM assembly Raspberry PI */
/* program zumkeller4.s */
Line 1,379 ⟶ 1,527:
/***************************************************/
.include "../affichage.inc"
</syntaxhighlight>
</lang>
<pre>
Program start
Line 1,412 ⟶ 1,560:
=={{header|C sharp|C#}}==
{{trans|Go}}
<langsyntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Linq;
Line 1,507 ⟶ 1,655:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>The first 220 Zumkeller numbers are:
Line 1,536 ⟶ 1,684:
 
=={{header|C++}}==
<syntaxhighlight lang="cpp>#include <iostream">
<lang cpp>
#include <iostream>
#include <cmath>
#include <vector>
Line 1,546 ⟶ 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<uint> zumz;
for (uint n = 2; zumz.size() < 220; n++)
if (isZum(n))
zumz.push_back(n);
cout << zumz << endl << endl;
 
cout << "First 40 odd Zumkeller numbers:" << endl;
int main()
vector<uint> zumz2;
{
for (uint n = 2; zumz2.size() < 40; n++)
vector<int> zumz;
if (n % 2 && isZum(n))
int n = 2;
zumz2.push_back(n);
cout << "Thezumz2 first<< 220endl Zumkeller<< numbers:\n\n"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 not ending in 5:\n\n" << endl;
vector<intuint> zumz2zumz3;
for (uint n = 2; zumz3.size() < 40; n++)
n = 2;
if (n % 2 && (n % 10) != 5 && isZum(n))
while (zumz2.size() < 40)
zumz3.push_back(n);
{
cout << zumz3 << 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] << ' ';
}
 
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 we get here and n is odd or n has at least 24 divisors it's a zum!
if (n % 2 || d.size() >= 24)
return true;
 
if (!(s % 2) && d[d.size() - 1] <= s / 2)
for (uint x = 2; (uint) log2(x) < (d.size() - 1); x++) // using log2 prevents overflow
{
if (sum_subset_unrank_bin(d, x) == s / 2)
//using log2 prevents overflow
return true; // congratulations it's a zum num!!
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;
}</syntaxhighlight>
}
 
</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,864 ⟶ 1,961:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>The first 220 Zumkeller numbers are:
Line 1,891 ⟶ 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,935 ⟶ 2,133:
 
"First 40 odd Zumkeller numbers not ending with 5:" print
40 odd-zumkellers-no-5 8 show</langsyntaxhighlight>
{{out}}
<pre>
Line 1,966 ⟶ 2,164:
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 2,056 ⟶ 2,254:
}
fmt.Println()
}</langsyntaxhighlight>
 
{{out}}
Line 2,089 ⟶ 2,287:
=={{header|Haskell}}==
{{Trans|Python}}
<langsyntaxhighlight lang="haskell">import Data.List (group, sort)
import Data.List.Split (chunksOf)
import Data.Numbers.Primes (primeFactors)
Line 2,161 ⟶ 2,359:
 
justifyRight :: Int -> Char -> String -> String
justifyRight n c = (drop . length) <*> (replicate n c <>)</langsyntaxhighlight>
{{Out}}
<pre>First 220 Zumkeller numbers:
Line 2,193 ⟶ 2,391:
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 2,307 ⟶ 2,535:
 
}
</syntaxhighlight>
</lang>
 
{{out}}
Line 2,336 ⟶ 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 2,386 ⟶ 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 2,420 ⟶ 2,750:
=={{header|Kotlin}}==
{{trans|Java}}
<langsyntaxhighlight lang="scala">import java.util.ArrayList
import kotlin.math.sqrt
 
Line 2,528 ⟶ 2,858:
return divisors
}
}</langsyntaxhighlight>
{{out}}
<pre>First 220 Zumkeller numbers:
Line 2,556 ⟶ 2,886:
 
=={{header|Lobster}}==
<langsyntaxhighlight lang="Lobster">import std
 
// Derived from Julia and Python versions
Line 2,616 ⟶ 2,946:
print "\n\n40 odd Zumkeller numbers:"
printZumkellers(40, true)
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,650 ⟶ 2,980:
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}}
<langsyntaxhighlight lang="Nim">import math, strutils
 
template isEven(n: int): bool = (n and 1) == 0
Line 2,723 ⟶ 3,085:
inc count
stdout.write if count mod 8 == 0: '\n' else: ' '
inc n, 2</langsyntaxhighlight>
 
{{out}}
Line 2,751 ⟶ 3,113:
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>
modified [[practical numbers]] and [[Factors_of_an_integer#using_Prime_decomposition]]
Now using the trick, that one partition sum must include n and improved recursive search.<BR>
<lang pascal>program zumkeller;
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}
,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
tPottItem = recordUint64;
tDivisors = array [0..HCN_DivCnt-1] of tItem;
potPrim,
tpDivisor = pUint64;
potMax :Uint32;
const
end;
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 =
tprimeFac = record
// 2*3*5*7*11*13*17*19*23*29*31 = 2E11
pfPrims : array[0..13] of tPot;
tprimeFac = packed record
pfSumOfDivs :Uint64;
pfCntpfSumOfDivs,
pfRemain : Uint64; //n div (p[0]^[pPot[0] *...) can handle primes <=821641^2 = 6.7e11
pfDivCnt,
pfNumpfpotPrim : array[0..9] of : Uint32UInt32;//+10*4 = 56 Byte
pfpotMax : array[0..9] of byte; //10 = 66
pfMaxIdx : Uint16; //68
pfDivCnt : Uint32; //72
end;
 
tSmallPrimestPrimeDecompField = array[0..6541SizePrDeFe-1] of WordtprimeFac;
tPrimes = array[0..65535] of Uint32;
tItem = NativeUint;
tDivisors = array of tItem;
tpDivisor = pNativeUint;
var
SmallPrimes: tSmallPrimes;
primeDecomp: tprimeFac;
 
var
SmallPrimes: tPrimes;
//######################################################################
//prime decomposition
procedure InitSmallPrimes;
//only odd numbers
const
MAXLIMIT = (821641-1) shr 1;
var
pr : array[0..MAXLIMIT] of byte;
pr,testPr,j,maxprimidx: Uint32;
p,j,d,flipflop :NativeUInt;
isPrime : boolean;
Begin
maxprimidx := 0;
SmallPrimes[0] := 2;
fillchar(pr[0],SizeOf(pr),#0);
pr := 3;
p := 0;
repeat
isprime := true;
j := 0;
repeat
testPrp :+= SmallPrimes[j];1
IF sqr(testPr) >until pr[p]= then0;
j := break(p+1)*p*2;
if If pr mod testPr = 0j>MAXLIMIT then
BeginBREAK;
isprimed := false2*p+1;
break;repeat
endpr[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);
until falseend;
d += 2*flipflop;
p+=flipflop;
flipflop := 3-flipflop;
until (p > MAXLIMIT) OR (j>High(SmallPrimes));
end;
 
function OutPots(const pD:tprimeFac;n:NativeInt):Ansistring;
if isprime then
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
inc(maxprimidx);if n>0 then
SmallPrimes[maxprimidx]: result += pr'*';
str(pFpotPrim[n],s);
result += s;
if pfpotMax[n] >1 then
Begin
str(pfpotMax[n],s);
result += '^'+s;
end;
end;
If pfRemain >1 then
inc(pr,2);
Begin
until pr > 1 shl 16 -1;
str(pfRemain,s);
result += '*'+s;
end;
str(pfSumOfDivs,s);
result += '_SoD_'+s+'<';
end;
end;
 
function CnvtoBASE(var dgt:tDigits;n:Uint64;base:NativeUint):NativeInt;
function DivCount(const primeDecomp:tprimeFac):NativeUInt;inline;
//n must be multiple of base
begin
var
result := primeDecomp.pfDivCnt;
q,r: Uint64;
end;
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;
function SumOfDiv(const primeDecomp:tprimeFac):Uint64;inline;
while (result<i) AND (dgtDgts[result] = 0) do
begin
inc(result);
result := primeDecomp.pfSumOfDivs;
inc(result);
end;
end;
 
function IncByBaseInBase(var dgt:tDigits;base:NativeInt):NativeInt;
procedure PrimeDecomposition(n:Uint32;var res:tprimeFac);
var
q :NativeInt;
DivSum,fac:Uint64;
i,pr,cnt,DivCnt,quot{to minimize divisions} : NativeUint;
Begin
res.pfNumwith :=dgt n;do
cnt := 0;
DivCnt := 1;
DivSum := 1;
i := 0;
if n <= 1 then
Begin
withresult res.pfPrims[0]:= do0;
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
potPrimpfDivCnt := n1;
potMax pfSumOfDivs := 1;
pfRemain := n+i;
pfMaxIdx := 0;
end;
 
cnt := 1;
//first 2 make n+i even
end
i := n AND 1;
else
repeat
prwith := SmallPrimespdf[i]; do
IF pr*pr> if n+i > 0 then
Break;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 quotnow :=index nin div pr;SmallPrimes
i IF pr*quot := n then0;
repeat
with res do
//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
with pfPrimspfpotPrim[CntpfMaxIdx] do:= pr;
BeginpfpotMax[pfMaxIdx] := j;
pfDivCnt potPrim :*= prj+1;
potMaxfac := 0pr;
fac := pr;repeat
repeatpfRemain := pfRemain DIV pr;
n := quotdec(j);
fac quot :*= quot div pr;
until j<= inc(potMax)0;
facpfSumOfDivs *= (fac-1)DIV(pr-1);
until pr*quot <> ninc(pfMaxIdx);
DivCnt *= (potMax+1);
DivSum *= (fac-1)DIV(pr-1);
end;
inc(Cnt);
end;
inc(i) k += pr;
j := IncByBaseInBase(dgt,pr);
until k >= SizePrDeFe;
until false;
 
//a big prime left over?
//correct sum of & count of divisors
IF n > 1 then
for i with:= res0 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);
with pfPrims[Cnt] do
Check_rek_depth(pfSumOfDivs shr 1-n,pFDivCnt-1);
write(pfSumOfDivs shr 1:10,' = ');
sum := n;
while depth >= 0 do
Begin
potPrimsum :+= nDivUsedIdx[depth];
potMax := 1write(DivUsedIdx[depth],'+');
dec(depth);
end;
incwrite(Cntn,' = ',sum);
DivCnt *= 2;end
else
DivSum *= n+1;
write(' no zumkeller ');
end;
end;
res.pfCnt:= cnt;
res.pfDivCnt := DivCnt;
res.pfSumOfDivs := DivSum;
end;
 
Line 2,913 ⟶ 3,526:
end;
 
procedure GetDivs(varconst primeDecomppD:tprimeFac;var Divs,SumOfDivs:tDivisors);
var
pDivs : tpDivisor;
i,len,j,l,p,pPot,k : NativeIntUInt64;
i,len,j,l,p,k: Int32;
Begin
i := DivCount(primeDecomp)pD.pfDivCnt;
setlength(Divs,i);
 
pDivs := @Divs[0];
pDivs[0] := 1;
len := 1;
l := 1;
with pD do
For i := 0 to primeDecomp.pfCnt-1 do
Begin
with primeDecomp.pfPrims[i] do
For i := 0 to pfMaxIdx-1 do
Begin
begin
//Multiply every divisor before with the new primefactors
//and append them to the list
k := potMax-1pfpotMax[i];
p := potPrimpfpotPrim[i];
pPot :=1;
repeat
Line 2,941 ⟶ 3,554:
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);
var
begin
HasSum: array of byte;
GetDivs(pD,Divs:tDivisors,SUmOfDivs);
finished := false;
depth := 0;
pDiv := @Divs[0];
end;
 
functionprocedure isZumKellerCheck_rek(varSoD Divs:tDivisors Int64;Middlei: NativeInt):boolean;
//mark sum and than shift by next divisor == add
//for practical numbers every sum must be marked
//modified for zumkeller
var
hs0,hs1sum : pByteInt64;
idx, j, i,maxlimit : NativeInt;
begin
if finished then
hs0 := @HasSum[0];
EXIT;
hs0[0] := 1; //empty set
if rec_Cnt >RECCOUNTMAX then
maxlimit := 0;
//Stopps at last by Divs[?] = n
for idx := 0 to High(Divs) do
begin
irec_Cnt := Divs[idx]-1;
Iffinished i:= > middle thentrue;
BREAKexit;
IF maxlimit >= middle-i then
Begin
maxlimit := middle-i;
if hs0[maxLimit] <> 0 then
EXIT(true)
end;
//next sum
hs1 := @hs0[i];
For j := maxlimit downto 0 do
hs1[j] := hs1[j] OR hs0[j];
maxlimit += i;
end;
inc(rec_Cnt);
result := false;
 
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: Uint32NativeUint;var pD:tPrimefac): boolean;
var
sumSoD,lesum : NativeUIntInt64;
Div_cnt,i,pracLmt: NativeInt;
begin
rec_Cnt := 0;
PrimeDecomposition(n,primeDecomp);
SoD:= pd.pfSumOfDivs;
sum := SumOfDiv(primeDecomp);
//sum must be even and n not deficient
if Odd(sumSoD) ORor (sum SoD< 2*n) thenTHEN
EXIT(false);
//if Odd(n) then Exit(Not(odd(sum)));// to be tested
//Now one needs to get the divisors
GetDivs(primeDecomp,Divs);
sum := sum shr 1;
 
leSoD := length(HasSum)SoD shr 1-n;
ifIf leSoD < sum2 then //0,1 is always true
Exit(true);
Begin
le := sum +1;
setlength(HasSum,0);
setlength(HasSum, le);
end
else
fillChar(HasSum[0],sum,#0);
 
Div_cnt := pD.pfDivCnt;
result := isZumKeller(Divs,sum);
end;
 
if Not(odd(n)) then
procedure OutSol(sol:array of Uint32;colWidth,ColCount,limit:NativeInt);
if ((n mod 18) in [6,12]) then
var
EXIT(true);
i,col: NativeInt;
 
Begin
//Now one needs to get the divisors
col := 0;
Init_check_rec(pD,Divs,SumOfDivs);
For i := 0 to limit-1 do
 
pracLmt:= 0;
if Not(odd(n)) then
begin
For i := 1 to Div_Cnt do
write(Sol[i]:colWidth);
inc(col);Begin
if col =sum ColCount:= thenSumOfDivs[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
writeln;if pfRemain > 1 then
col : EXIT((pfRemain<=i) 0;OR (i<=sum))
else
EXIT((pfpotPrim[pfMaxIdx-1]<=i)OR (i<=sum));
end;
end;
 
writeln;
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;
 
const
ColCnt = 20;
MAX = 220;
 
var
T0Ofs,i,n : Int64NativeUInt;
sol Max: array of Uint32NativeUInt;
 
n, col,limit,count: NativeInt;
procedure Init_Sieve(n:NativeUint);
//Init Sieve i,oFs are Global
begin
i := n MOD SizePrDeFe;
InitSmallPrimes;
Ofs := (n DIV SizePrDeFe)*SizePrDeFe;
setlength(HasSum,8);
SieveOneSieve(PrimeDecompField,Ofs);
setlength(sol,MAX);
end;
 
procedure GetSmall(MaxIdx:Int32);
T0 := GetTickCount64;
var
col := ColCnt;
ZK: Array of Uint32;
count := 0;
Limit idx:= MAXUInt32;
Begin
n := 1;
If MaxIdx<1 then
writeln('The first ',MAX,' zumkeller numbers');
EXIT;
writeln('The first ',MaxIdx,' zumkeller numbers');
Init_Sieve(0);
setlength(ZK,MaxIdx);
idx := Low(ZK);
repeat
if GetZumKeller(n,PrimeDecompField[i]) then
beginBegin
solZK[countidx] := n;
inc(countidx);
end;
inc(i);
inc(n);
If i > High(PrimeDecompField) then
until count = Limit;
begin
OutSol(sol,4,20,Limit);
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);
count :=0;
setlength(ZK,MaxIdx);
Limit := 40;
idx := Low(ZK);
repeat
if GetZumKeller(n,PrimeDecompField[i]) then
beginBegin
solZK[countidx] := n;
inc(countidx);
end;
inc(i,2);
inc(n,2);
If i > High(PrimeDecompField) then
until count = Limit;
begin
OutSol(sol,8,10,Limit);
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);
n := 1;
var
count :=0;
ZK: Array of Uint32;
Limit := 40;
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
beginBegin
solZK[countidx] := n;
inc(countidx);
end;
inc(i,2);
inc(n,2);
ifIf n MODmod 5 = 0 then
begin
inc(i,2);
inc(n,2);
until count = Limitend;
If i > High(PrimeDecompField) then
OutSol(sol,8,10,Limit);
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-T0;
GetSmall(220);
writeln('runtime ',T0/1000:0:3,' s');
setlengthGetOdd(HasSum, 040);
GetOddNot5(40);
{$IFNDEF UNIX} readln; {$ENDIF}
end.
 
writeln;
</lang>
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
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
Line 3,109 ⟶ 3,876:
 
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
Line 3,115 ⟶ 3,883:
 
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
Line 3,120 ⟶ 3,889:
1095633 1108107 1145529 1162161 1198197 1224531 1270269 1307691 1324323 1378377
 
Start 1 at 1
runtime 0.441 s
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
Real time: 0.579 s User time: 0.533 s Sys. time: 0.042 s CPU share: 99.41 %
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 3,171 ⟶ 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 3,201 ⟶ 4,012:
=={{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 3,213 ⟶ 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 3,223 ⟶ 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 3,280 ⟶ 4,094:
 
=={{header|PicoLisp}}==
<langsyntaxhighlight lang="PicoLisp">(de propdiv (N)
(make
(for I N
Line 3,331 ⟶ 4,145:
(and
(=0 (% C 8))
(prinl) ) ) )</langsyntaxhighlight>
{{out}}
<pre>
Line 3,362 ⟶ 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 3,394 ⟶ 4,208:
print("\n\n40 odd Zumkeller numbers:")
printZumkellers(40, True)
</langsyntaxhighlight>{{out}}
<pre>
220 Zumkeller numbers:
Line 3,432 ⟶ 4,246:
Relying on the standard Python libraries, as an alternative to importing SymPy:
 
<langsyntaxhighlight lang="python">'''Zumkeller numbers'''
 
from itertools import (
Line 3,634 ⟶ 4,448:
# MAIN ---
if __name__ == '__main__':
main()</langsyntaxhighlight>
{{Out}}
<pre>First 220 Zumkeller numbers:
Line 3,671 ⟶ 4,485:
{{trans|Zkl}}
 
<langsyntaxhighlight lang="racket">#lang racket
 
(require math/number-theory)
Line 3,711 ⟶ 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 3,734 ⟶ 4,548:
=={{header|Raku}}==
(formerly Perl 6)
{{libheader|ntheory}}
{{works with|Rakudo|2019.07.1}}
<syntaxhighlight lang="raku" line>use ntheory:from<Perl5> <factor is_prime>;
 
<lang perl6>use ntheory:from<Perl5> <factor is_prime>;
 
sub zumkeller ($range) {
$range.grep: -> $maybe {
next if $maybe < 3 or $maybe.&is_prime;
nextmy if@divisors = $maybe.&is_primefactor.combinations».reduce( &[×] ).unique.reverse;
next unless [and] @divisors > 2, @divisors %% 2, (my $sum = @divisors.sum) %% 2, ($sum /= 2) ≥ $maybe;
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 =for 1; $c <..^ @divisors /2 2;-> ++$c) {
@divisors.combinations($c).map: -> $d {
next if (sum $d).sum != $sum;
$zumkeller = True and last TEST;
}
}
Line 3,763 ⟶ 4,575:
 
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";</langsyntaxhighlight>
{{out}}
<pre>First 220 Zumkeller numbers:
Line 3,796 ⟶ 4,608:
=={{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 3,886 ⟶ 4,698:
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>
Line 3,909 ⟶ 4,721:
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
load "stdlib.ring"
 
Line 4,074 ⟶ 4,886:
last -= 1
end
</syntaxhighlight>
</lang>
Output:
<pre>
Line 4,097 ⟶ 4,909:
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}}==
<langsyntaxhighlight lang="rust">
use std::convert::TryInto;
 
Line 4,185 ⟶ 5,067:
}
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 4,203 ⟶ 5,085:
 
=={{header|Sidef}}==
<langsyntaxhighlight lang="ruby">func is_Zumkeller(n) {
 
return false if n.is_prime
Line 4,236 ⟶ 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 4,250 ⟶ 5,132:
 
=={{header|Standard ML}}==
<langsyntaxhighlight lang="Standard ML">
exception Found of string ;
 
Line 4,303 ⟶ 5,185:
 
end;
</syntaxhighlight>
</lang>
call loop and output - interpreter
<langsyntaxhighlight lang="Standard ML">
- val Zumkellerlist = fn step => fn no5 =>
let
Line 4,338 ⟶ 5,220:
742203, 783783, 793611, 812889, 837837, 891891, 908523, 960687, 999999, 1024947, 1054053, 1072071, 1073709, 1095633, 1108107, 1145529,
1162161, 1198197, 1224531, 1270269, 1307691, 1324323, 1378377
</syntaxhighlight>
</lang>
 
=={{header|Swift}}==
Line 4,344 ⟶ 5,226:
{{trans|Go}}
 
<langsyntaxhighlight lang="swift">import Foundation
 
extension BinaryInteger {
Line 4,404 ⟶ 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 4,411 ⟶ 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#}}
<langsyntaxhighlight lang="vbnet">Module Module1
Function GetDivisors(n As Integer) As List(Of Integer)
Dim divs As New List(Of Integer) From {
Line 4,513 ⟶ 5,561:
End While
End Sub
End Module</langsyntaxhighlight>
{{out}}
<pre>The first 220 Zumkeller numbers are:
Line 4,540 ⟶ 5,588:
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}}==
Line 4,546 ⟶ 5,714:
{{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.
<langsyntaxhighlight ecmascriptlang="wren">import "./math" for Int, Nums
import "./fmt" for Fmt
import "io" for Stdout
 
Line 4,612 ⟶ 5,780:
i = i + 2
}
System.print()</langsyntaxhighlight>
 
{{out}}
Line 4,645 ⟶ 5,813:
=={{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 4,668 ⟶ 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 4,679 ⟶ 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 4,708 ⟶ 5,876:
1145529 1162161 1198197 1224531 1270269 1307691 1324323 1378377
</pre>
[[Link title]]
2,083

edits