#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+CgoKdGVtcGxhdGUgPHR5cGVuYW1lIGludF90eXBlLAogICAgICAgICAgY2xhc3MgPSB0eXBlbmFtZSBzdGQ6OmVuYWJsZV9pZjxzdGQ6OmlzX3Vuc2lnbmVkPGludF90eXBlPjo6dmFsdWU+Ojp0eXBlPgpzdGQ6OnN0cmluZyB0b19iaW5hcnkoaW50X3R5cGUgbnVtKQp7CiAgICBpZiAobnVtID09IDApCiAgICAgICAgcmV0dXJuIHN0ZDo6c3RyaW5nKDEsICcwJyk7CgogICAgLy8gYmVnaW4gd2l0aCBtb3N0IHNpZ25pZmljYW50IGJpdDoKICAgIGludF90eXBlIG1hc2sgPSAxIDw8IChzdGQ6Om51bWVyaWNfbGltaXRzPGludF90eXBlPjo6ZGlnaXRzIC0gMSk7CgogICAgd2hpbGUgKG1hc2sgJiYgIShtYXNrJm51bSkpIC8vIHNraXAgb3ZlciBsZWFkaW5nIDBzCiAgICAgICAgbWFzayA+Pj0gMTsKCiAgICBzdGQ6OnN0cmluZyByZXN1bHQ7CiAgICB3aGlsZSAobWFzaykKICAgIHsKICAgICAgICByZXN1bHQgKz0gKG1hc2sgJiBudW0pID8gJzEnIDogJzAnOwogICAgICAgIG1hc2sgPj49IDE7CiAgICB9CgogICAgcmV0dXJuIHJlc3VsdDsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIGludF90eXBlLAogICAgICAgICAgY2xhc3MgPSB0eXBlbmFtZSBzdGQ6OmVuYWJsZV9pZjxzdGQ6OmlzX3Vuc2lnbmVkPGludF90eXBlPjo6dmFsdWU+Ojp0eXBlPgp1bnNpZ25lZCBncm91cHNfb2ZfMXMoaW50X3R5cGUgbnVtKQp7CiAgICBpbnRfdHlwZSBtYXNrID0gMTsKICAgIGJvb2wgaW5fZ3JvdXAgPSBmYWxzZTsKICAgIHVuc2lnbmVkIGNvdW50ID0gMDsKCiAgICB3aGlsZSAobWFzaykKICAgIHsKICAgICAgICBpZiAobWFzayAmIG51bSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICghaW5fZ3JvdXApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGluX2dyb3VwID0gdHJ1ZTsKICAgICAgICAgICAgICAgICsrY291bnQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgICAgICBpbl9ncm91cCA9IGZhbHNlOwoKICAgICAgICBtYXNrIDw8PSAxOwogICAgfQoKICAgIHJldHVybiBjb3VudDsKfQoKaW50IG1haW4oKQp7CiAgICBjb25zdCB1bnNpZ25lZCB2YWx1ZSA9IDE4MzsKICAgIHN0ZDo6Y291dCA8PCB2YWx1ZSA8PCAiOiAiIDw8IHRvX2JpbmFyeSh2YWx1ZSkgPDwgIiwgIjsKICAgIHN0ZDo6Y291dCA8PCBncm91cHNfb2ZfMXModmFsdWUpIDw8ICIgZ3JvdXBzIG9mIDEuXG4iOwp9