long straightforward(long n) {
return (0..n).sum(Long.&bitCount)
}
assert (0..
10).
collect(this.
&straightforward
) == [0, 1, 2, 4, 5, 7, 9, 12, 13, 15, 17]
long separateDigits(long n) {
++n
long acc = 0
long mask = 0
for (long scanbit = 1; scanbit < n; scanbit <<= 1) {
mask |= scanbit
long remainder = n & mask
acc += (n - remainder) >> 1
if (n & scanbit)
acc += remainder - scanbit
}
return acc
}
(0..
100).
each { assert separateDigits
(it
) == straightforward
(it
) }
bG9uZyBzdHJhaWdodGZvcndhcmQobG9uZyBuKSB7CiAgICByZXR1cm4gKDAuLm4pLnN1bShMb25nLiZiaXRDb3VudCkKfQphc3NlcnQgKDAuLjEwKS5jb2xsZWN0KHRoaXMuJnN0cmFpZ2h0Zm9yd2FyZCkgPT0gWzAsIDEsIDIsIDQsIDUsIDcsIDksIDEyLCAxMywgMTUsIDE3XQoKbG9uZyBzZXBhcmF0ZURpZ2l0cyhsb25nIG4pIHsKICAgICsrbgogICAgbG9uZyBhY2MgPSAwCiAgICBsb25nIG1hc2sgPSAwCiAgICBmb3IgKGxvbmcgc2NhbmJpdCA9IDE7IHNjYW5iaXQgPCBuOyBzY2FuYml0IDw8PSAxKSB7CiAgICAgICAgbWFzayB8PSBzY2FuYml0CiAgICAgICAgbG9uZyByZW1haW5kZXIgPSBuICYgbWFzawogICAgICAgIGFjYyArPSAobiAtIHJlbWFpbmRlcikgPj4gMQogICAgICAgIGlmIChuICYgc2NhbmJpdCkKICAgICAgICAgICAgYWNjICs9IHJlbWFpbmRlciAtIHNjYW5iaXQKICAgIH0KICAgIHJldHVybiBhY2MKfQooMC4uMTAwKS5lYWNoIHsgYXNzZXJ0IHNlcGFyYXRlRGlnaXRzKGl0KSA9PSBzdHJhaWdodGZvcndhcmQoaXQpIH0=