#include <cmath>
#include <iostream>
#include <vector>
struct div_with_positive_remainder_t
{
int quot;
int rem;
};
div_with_positive_remainder_t div_with_positive_remainder(int x, int y)
{
if (y == 0) {
throw std::runtime_error("division by zero");
}
int r = x % y;
if (r < 0) {
r += std::abs(y);
}
int q = (x - r) / y;
return {q, r};
}
std::vector<int> to_negbase(int n, int negbase = -2)
{
std::vector<int> res;
while (n != 0) {
auto div = div_with_positive_remainder(n, negbase);
res.push_back(div.rem);
n = div.quot;
}
return res;
}
int to_int(const std::vector<int> &digits, int base = -2) {
int res = 0;
int power = 1;
for (auto digit : digits){
res += power * digit;
power *= base;
}
return res;
}
std::vector<int> negative_base(const std::vector<int> &v)
{
return to_negbase(-to_int(v));
}
void print(const std::vector<int>& v, int negbase = -2)
{
std::cout << to_int(v, negbase) << " = [";
for (auto e: v) {
std::cout << e << " ";
}
std::cout << "](" << negbase << ")" << std::endl;
}
int main()
{
print(to_negbase(2369, -10), -10); // 18449(-10)
print(to_negbase(1234, -8), -8); // 16462(-10)
print(to_negbase(23));
print(negative_base({1, 1, 0, 1, 0, 1, 1}));
}
I2luY2x1ZGUgPGNtYXRoPgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDx2ZWN0b3I+CgpzdHJ1Y3QgZGl2X3dpdGhfcG9zaXRpdmVfcmVtYWluZGVyX3QKewogICAgaW50IHF1b3Q7CiAgICBpbnQgcmVtOwp9OwoKZGl2X3dpdGhfcG9zaXRpdmVfcmVtYWluZGVyX3QgZGl2X3dpdGhfcG9zaXRpdmVfcmVtYWluZGVyKGludCB4LCBpbnQgeSkKewogICAgaWYgKHkgPT0gMCkgewogICAgICAgIHRocm93IHN0ZDo6cnVudGltZV9lcnJvcigiZGl2aXNpb24gYnkgemVybyIpOwogICAgfQogICAgaW50IHIgPSB4ICUgeTsKICAgIGlmIChyIDwgMCkgewogICAgICAgIHIgKz0gc3RkOjphYnMoeSk7CiAgICB9CiAgICBpbnQgcSA9ICh4IC0gcikgLyB5OwogICAgcmV0dXJuIHtxLCByfTsKfQoKc3RkOjp2ZWN0b3I8aW50PiB0b19uZWdiYXNlKGludCBuLCBpbnQgbmVnYmFzZSA9IC0yKQp7CiAgICBzdGQ6OnZlY3RvcjxpbnQ+IHJlczsKICAgIAogICAgd2hpbGUgKG4gIT0gMCkgewogICAgICAgIGF1dG8gZGl2ID0gZGl2X3dpdGhfcG9zaXRpdmVfcmVtYWluZGVyKG4sIG5lZ2Jhc2UpOwogICAgICAgIHJlcy5wdXNoX2JhY2soZGl2LnJlbSk7CiAgICAgICAgbiA9IGRpdi5xdW90OwogICAgfQogICAgcmV0dXJuIHJlczsKfQoKaW50IHRvX2ludChjb25zdCBzdGQ6OnZlY3RvcjxpbnQ+ICZkaWdpdHMsIGludCBiYXNlID0gLTIpIHsKICAgIGludCByZXMgPSAwOwogICAgaW50IHBvd2VyID0gMTsKICAgIGZvciAoYXV0byBkaWdpdCA6IGRpZ2l0cyl7CiAgICAgICAgcmVzICs9IHBvd2VyICogZGlnaXQ7CiAgICAgICAgcG93ZXIgKj0gYmFzZTsKICAgIH0KICAgIHJldHVybiByZXM7Cn0KCnN0ZDo6dmVjdG9yPGludD4gbmVnYXRpdmVfYmFzZShjb25zdCBzdGQ6OnZlY3RvcjxpbnQ+ICZ2KQp7CiAgICByZXR1cm4gdG9fbmVnYmFzZSgtdG9faW50KHYpKTsKfQoKdm9pZCBwcmludChjb25zdCBzdGQ6OnZlY3RvcjxpbnQ+JiB2LCBpbnQgbmVnYmFzZSA9IC0yKQp7CiAgICBzdGQ6OmNvdXQgPDwgdG9faW50KHYsIG5lZ2Jhc2UpIDw8ICIgPSBbIjsKICAgIGZvciAoYXV0byBlOiB2KSB7CiAgICAgICAgc3RkOjpjb3V0IDw8IGUgPDwgIiAiOwogICAgfQogICAgc3RkOjpjb3V0IDw8ICJdKCIgPDwgbmVnYmFzZSA8PCAiKSIgPDwgc3RkOjplbmRsOwp9CgoKaW50IG1haW4oKQp7CiAgICBwcmludCh0b19uZWdiYXNlKDIzNjksIC0xMCksIC0xMCk7IC8vIDE4NDQ5KC0xMCkKICAgIHByaW50KHRvX25lZ2Jhc2UoMTIzNCwgLTgpLCAtOCk7ICAgLy8gMTY0NjIoLTEwKQogICAgcHJpbnQodG9fbmVnYmFzZSgyMykpOwoKICAgIHByaW50KG5lZ2F0aXZlX2Jhc2UoezEsIDEsIDAsIDEsIDAsIDEsIDF9KSk7IAp9Cg==