#include <iostream>
uint32_t node_id = 0;
uint32_t failed = 0;
uint32_t popcnt(const uint32_t x)
{ return __builtin_popcount(x); }
uint32_t getMSBindex(const uint32_t x)
{ return 31 - __builtin_clz(x); }
uint32_t getMSBmask(const uint32_t x)
{ return 1 << getMSBindex(x); }
uint32_t parent(const uint32_t node)
{
uint32_t x = node;
while (x > 2)
{
const uint32_t y = x + popcnt(x);
const uint32_t bit = getMSBmask(y & ~x);
const uint32_t mask = (bit << 1) - 1;
x = (x & mask) + popcnt(x & ~mask);
}
return node + 1 + (x == 1);
}
uint32_t test(const int32_t depth)
{
if (depth)
{
const uint32_t left = test(depth - 1);
const uint32_t right = test(depth - 1);
++node_id;
if (depth == 1 && left != node_id) ++failed;
if (depth == 1 && right != node_id) ++failed;
}
else
{
++node_id;
}
return (depth == 0)? parent(node_id): 0;
}
int main()
{
test(23);
std::cout << "nodes: " << node_id << '\n';
std::cout << "failed: " << failed << '\n';
}