Zumkeller numbers: Difference between revisions
Content added Content deleted
m (→{{header|Pascal}}: too much copy and paste...) |
(→{{header|C++}}: improvements) |
||
Line 1,536: | Line 1,536: | ||
=={{header|C++}}== |
=={{header|C++}}== |
||
<lang cpp> |
<lang cpp>#include <iostream> |
||
#include <iostream> |
|||
#include <cmath> |
#include <cmath> |
||
#include <vector> |
#include <vector> |
||
Line 1,546: | Line 1,545: | ||
using namespace std; |
using namespace std; |
||
// |
// 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 the the binary ordered subset of rank r. |
||
//Adapted from Sympy |
// Adapted from Sympy implementation. |
||
vector< |
vector<uint> subset_unrank_bin(vector<uint>& d, uint r); |
||
vector |
vector<uint> factors(uint x); |
||
bool isPrime( |
bool isPrime(uint number); |
||
bool isZum( |
bool isZum(uint n); |
||
ostream& operator<<(ostream& os, const vector<uint>& zumz) { |
|||
for (uint i = 0; i < zumz.size(); i++) { |
|||
if (i % 10 == 0) |
|||
os << endl; |
|||
os << setw(10) << zumz[i] << ' '; |
|||
} |
|||
return os; |
|||
} |
|||
int main() { |
|||
cout << "First 220 Zumkeller numbers:" << endl; |
|||
vector<uint> zumz; |
|||
for (uint n = 2; zumz.size() < 220; n++) |
|||
if (isZum(n)) |
|||
zumz.push_back(n); |
|||
cout << zumz << endl << endl; |
|||
cout << "First 40 odd Zumkeller numbers:" << endl; |
|||
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 << zumz2 << 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 << "First 40 odd Zumkeller numbers not ending in 5:" << endl; |
|||
vector<uint> zumz3; |
|||
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 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; |
|||
n /= 2; |
|||
if (rem) |
|||
bin[length - 1 - i] = 1; |
|||
} |
|||
return bin; |
|||
bin = new int[length]; //array to hold result |
|||
for (int i = 0; i < length; i++) //fill with zeroes |
|||
bin[i] = 0; |
|||
//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 the sum of the binary ordered subset of rank r. |
||
//Adapted from Sympy |
// Adapted from Sympy implementation. |
||
uint sum_subset_unrank_bin(const vector<uint>& d, uint r) { |
|||
vector<uint> subset; |
|||
{ |
|||
// convert r to binary array of same size as d |
|||
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]); |
|||
} |
|||
} |
|||
// 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 |
vector<uint> factors(uint x) { |
||
vector<uint> result; |
|||
// this will loop from 1 to int(sqrt(x)) |
|||
for (uint i = 1; i * i <= x; i++) { |
|||
// Check if i divides x without leaving a remainder |
|||
if (x % i == 0) { |
|||
result.push_back(i); |
|||
if (x / i != i) |
|||
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.begin(), result.end()); |
|||
return result; |
|||
} |
|||
i++; |
|||
} |
|||
// Return the list of factors of x |
|||
return result; |
|||
} |
} |
||
bool isPrime( |
bool isPrime(uint number) { |
||
if (number < 2) return false; |
|||
{ |
|||
if (number == 2) return true; |
|||
if (number % 2 == 0) return false; |
|||
for (uint i = 3; i * i <= number; i += 2) |
|||
if (number % 2 == 0) return false; |
|||
if (number % i == 0) return false; |
|||
if (number % i == 0) return false; |
|||
return true; |
|||
} |
} |
||
bool isZum( |
bool isZum(uint 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 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) |
|||
//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; |
|||
{ |
|||
}</lang> |
|||
//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}} |
{{out}} |
||
<pre> |
<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 |
|||
942 945 948 952 960 966 972 978 980 984 |
|||
First 40 odd Zumkeller numbers: |
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 |
|||
14805 15015 15435 16065 16695 17325 17955 18585 19215 19305 |
|||
First 40 odd Zumkeller numbers not ending in 5: |
First 40 odd Zumkeller numbers not ending in 5: |
||
81081 153153 171171 189189 207207 223839 243243 261261 279279 297297 |
|||
351351 459459 513513 567567 621621 671517 729729 742203 783783 793611 |
|||
812889 837837 891891 908523 960687 999999 1024947 1054053 1072071 1073709 |
|||
1095633 1108107 1145529 1162161 1198197 1224531 1270269 1307691 1324323 1378377 |
|||
1095633 1108107 1145529 1162161 1198197 1224531 1270269 1307691 1324323 1378377 |
|||
*/ |
|||
</pre> |
</pre> |
||