#include <iostream>
#include <string>
#include <limits>
#include <type_traits>
template <typename int_type,
class = typename std::enable_if<std::is_unsigned<int_type>::value>::type>
std::string to_binary(int_type num)
{
if (num == 0)
return std::string(1, '0');
// begin with most significant bit:
int_type mask = 1 << (std::numeric_limits<int_type>::digits - 1);
while (mask && !(mask&num)) // skip over leading 0s
mask >>= 1;
std::string result;
while (mask)
{
result += (mask & num) ? '1' : '0';
mask >>= 1;
}
return result;
}
template <typename int_type,
class = typename std::enable_if<std::is_unsigned<int_type>::value>::type>
unsigned groups_of_1s(int_type num)
{
int_type mask = 1;
bool in_group = false;
unsigned count = 0;
while (mask)
{
if (mask & num)
{
if (!in_group)
{
in_group = true;
++count;
}
}
else
in_group = false;
mask <<= 1;
}
return count;
}
int main()
{
const unsigned value = 183;
std::cout << value << ": " << to_binary(value) << ", " ;
std::cout << groups_of_1s(value) << " groups of 1.\n";
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8bGltaXRzPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CgoKdGVtcGxhdGUgPHR5cGVuYW1lIGludF90eXBlLCAKICAgICAgICAgIGNsYXNzID0gdHlwZW5hbWUgc3RkOjplbmFibGVfaWY8c3RkOjppc191bnNpZ25lZDxpbnRfdHlwZT46OnZhbHVlPjo6dHlwZT4Kc3RkOjpzdHJpbmcgdG9fYmluYXJ5KGludF90eXBlIG51bSkKewogICAgaWYgKG51bSA9PSAwKQogICAgICAgIHJldHVybiBzdGQ6OnN0cmluZygxLCAnMCcpOwoKICAgIC8vIGJlZ2luIHdpdGggbW9zdCBzaWduaWZpY2FudCBiaXQ6CiAgICBpbnRfdHlwZSBtYXNrID0gMSA8PCAoc3RkOjpudW1lcmljX2xpbWl0czxpbnRfdHlwZT46OmRpZ2l0cyAtIDEpOwoKICAgIHdoaWxlIChtYXNrICYmICEobWFzayZudW0pKSAgICAgICAgICAgICAvLyBza2lwIG92ZXIgbGVhZGluZyAwcwogICAgICAgIG1hc2sgPj49IDE7CiAgICAKICAgIHN0ZDo6c3RyaW5nIHJlc3VsdDsKICAgIHdoaWxlIChtYXNrKQogICAgewogICAgICAgIHJlc3VsdCArPSAobWFzayAmIG51bSkgPyAnMScgOiAnMCc7CiAgICAgICAgbWFzayA+Pj0gMTsKICAgIH0KCiAgICByZXR1cm4gcmVzdWx0Owp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgaW50X3R5cGUsIAogICAgICAgICAgY2xhc3MgPSB0eXBlbmFtZSBzdGQ6OmVuYWJsZV9pZjxzdGQ6OmlzX3Vuc2lnbmVkPGludF90eXBlPjo6dmFsdWU+Ojp0eXBlPgp1bnNpZ25lZCBncm91cHNfb2ZfMXMoaW50X3R5cGUgbnVtKQp7CiAgICBpbnRfdHlwZSBtYXNrID0gMTsKICAgIGJvb2wgaW5fZ3JvdXAgPSBmYWxzZTsKICAgIHVuc2lnbmVkIGNvdW50ID0gMDsKCiAgICB3aGlsZSAobWFzaykKICAgIHsKICAgICAgICBpZiAobWFzayAmIG51bSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICghaW5fZ3JvdXApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGluX2dyb3VwID0gdHJ1ZTsKICAgICAgICAgICAgICAgICsrY291bnQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZSAKICAgICAgICAgICAgaW5fZ3JvdXAgPSBmYWxzZTsKCiAgICAgICAgbWFzayA8PD0gMTsKICAgIH0KCiAgICByZXR1cm4gY291bnQ7Cn0KCmludCBtYWluKCkKewogICAgY29uc3QgdW5zaWduZWQgdmFsdWUgPSAxODM7CiAgICBzdGQ6OmNvdXQgPDwgdmFsdWUgPDwgIjogIiA8PCB0b19iaW5hcnkodmFsdWUpIDw8ICIsICIgOwogICAgc3RkOjpjb3V0IDw8IGdyb3Vwc19vZl8xcyh2YWx1ZSkgPDwgIiBncm91cHMgb2YgMS5cbiI7Cn0=