#include <iostream>
#include <cassert>
using namespace std;
int parity1(unsigned long long n) {
int p = 0;
while (n) {
p ^= (n & 1);
n >>= 1;
}
return p;
}
int parity2(unsigned long long n) {
int p = 0;
while (n) {
p ^= 1;
n &= (n - 1); // Drop the lowest set bit of n
}
return p;
}
int precomputed_parity[1 << 16];
int parity3(unsigned long long n) {
return precomputed_parity[(n >> 48) & 0xffff] ^
precomputed_parity[(n >> 32) & 0xffff] ^
precomputed_parity[(n >> 16) & 0xffff] ^
precomputed_parity[n & 0xffff];
}
int main(int argc, char *argv[]) {
for (int i = 0; i < (1 << 16); i++) {
precomputed_parity[i] = parity2(i);
}
srand(time(nullptr));
if (argc == 2) {
unsigned long long n = atol(argv[1]);
assert(parity1(n) == parity2(n));
assert(parity2(n) == parity3(n));
cout << "n = " << n << ", parity = " << parity3(n) << endl;
} else {
for (int i = 0; i < 100; i++) {
unsigned long long n = rand();
assert(parity1(n) == parity2(n));
assert(parity2(n) == parity3(n));
cout << "n = " << n << ", parity = " << parity3(n) << endl;
}
}
return 0;
}