On this page

Notes

Peel the ones, then 2^k mod 37

· algorithms

lowbit walks every 1. A 37-slot table names the exponent, because 2^k is unique mod 37.

A nonnegative int nn. How many 11s does it have?

The brute loop always works. Smarter: take lowbit, that is the first 11, count it, then n -= lowbit and repeat until n=0n = 0.

int population(int n) {
int p = 0;
while (n > 0) {
n -= n & -n;
++p;
}
return p;
}

Side note: C++ already has std::popcount.

Now I want the positions. Same peel. The remaining job: given a lowbit m=2km = 2^{k}, recover kk.

A fat table

Hash it. Build an array long enough that index 2k2^{k} stores kk. I used 2202^{20}, which does not even cover every int, and every slot that is not a power of two is wasted.

std::array<int, (1 << 20) + 1> create_power_to_exponent_map_naive() {
std::array<int, (1 << 20) + 1> power_to_exponent_map = {};
for (int k = 0; k <= 20; ++k) {
power_to_exponent_map[1 << k] = k;
}
return power_to_exponent_map;
}

Compress with 37

The claim is that the residues 20,21,,2352^{0}, 2^{1}, \ldots, 2^{35} are pairwise distinct modulo 3737:

ij    2i/2j(mod37).i \neq j \implies 2^{i} \nequiv 2^{j} \pmod{37}.

So a table of length 3737 can store kk at index 2kmod372^{k} \bmod 37. I only need k30k \le 30 for a 32-bit int, but the residues still live in {0,1,,36}\{0, 1, \ldots, 36\}, so the array stays size 3737.

std::array<int, 37> create_power_to_exponent_map() {
std::array<int, 37> power_to_exponent_map = {};
for (int k = 0; k <= 30; ++k) {
power_to_exponent_map[static_cast<std::size_t>((1 << k) % 37)] = k;
}
return power_to_exponent_map;
}
const auto kPowerToExponentMap = create_power_to_exponent_map();
std::vector<int> find_bit_positions(int n) {
std::vector<int> positions;
while (n > 0) {
int lowbit = n & (-n);
int position = kPowerToExponentMap[static_cast<size_t>(lowbit % 37)];
positions.push_back(position);
n -= lowbit;
}
return positions;
}

Take n = 0b1110110. Peel: 212^{1}, 222^{2}, 242^{4}, 252^{5}, 262^{6}. Already 26=6427(mod37)2^{6} = 64 \equiv 27 \pmod{37}, so the table is doing real compression — slot 2727 holds 66.

Why no collisions

If 2i2j(mod37)2^{i} \equiv 2^{j} \pmod{37} with 0i<j0 \le i < j, then since gcd(2,37)=1\gcd(2, 37) = 1 we may cancel 2i2^{i} and obtain 2ji1(mod37)2^{j-i} \equiv 1 \pmod{37}. A collision is exactly when some positive exponent smaller than 3636 already yields 11. That is the language of multiplicative order.

Definitionmultiplicative order

Let n>1n > 1 be an integer and let aZa \in \mathbb{Z} satisfy gcd(a,n)=1\gcd(a, n) = 1. The multiplicative order of aa modulo nn is the smallest positive integer kk such that

ak1(modn).a^{k} \equiv 1 \pmod{n}.

It is denoted ordn(a)\operatorname{ord}_{n}(a).

The coprimality hypothesis is not decoration: it guarantees that some power of aa is congruent to 11, so a least such positive exponent exists. Note that a01(modn)a^{0} \equiv 1 \pmod{n} is trivial and does not count — zero is not a positive integer.

Since 3737 is prime and gcd(2,37)=1\gcd(2, 37) = 1, Fermat’s little theorem applies.

TheoremFermat's little theorem

Let pp be a prime number. Then for every integer aa,

apa(modp).a^{p} \equiv a \pmod{p}.

Equivalently, if pap \nmid a (that is, if gcd(a,p)=1\gcd(a, p) = 1), then

ap11(modp).a^{p-1} \equiv 1 \pmod{p}.

Taking a=2a = 2 and p=37p = 37, the second form gives

2361(mod37).2^{36} \equiv 1 \pmod{37}.

So ord37(2)\operatorname{ord}_{37}(2) exists, and it is at most 3636. Fermat does not say that 3636 is the least such exponent. If some m<36m < 36 already satisfied 2m1(mod37)2^{m} \equiv 1 \pmod{37}, the powers would collide. To pin the order down we need the following.

Proposition

Let n>1n > 1 and let aZa \in \mathbb{Z} with gcd(a,n)=1\gcd(a, n) = 1. Then for every integer k1k \ge 1,

ak1(modn)    ordn(a)k.a^{k} \equiv 1 \pmod{n} \iff \operatorname{ord}_{n}(a) \mid k.
Proof

Let m=ordn(a)m = \operatorname{ord}_{n}(a).

(\Leftarrow) By definition, am1(modn)a^{m} \equiv 1 \pmod{n}. Write k=mqk = mq for some integer q1q \ge 1. Then

ak=(am)q1q1(modn).a^{k} = \bigl(a^{m}\bigr)^{q} \equiv 1^{q} \equiv 1 \pmod{n}.

(\Rightarrow) By the division algorithm there exist unique integers q,rq, r such that k=mq+rk = mq + r and 0r<m0 \le r < m. Then

ak1(modn),amq+r1(modn),amqar1(modn).\begin{aligned} a^{k} &\equiv 1 \pmod{n}, \\ a^{mq+r} &\equiv 1 \pmod{n}, \\ a^{mq}\, a^{r} &\equiv 1 \pmod{n}. \end{aligned}

Since am1(modn)a^{m} \equiv 1 \pmod{n}, we have amq1(modn)a^{mq} \equiv 1 \pmod{n}, and therefore

amqaramq0(modn)    amq(ar1)0(modn).a^{mq}\, a^{r} - a^{mq} \equiv 0 \pmod{n} \implies a^{mq}\bigl(a^{r} - 1\bigr) \equiv 0 \pmod{n}.

As gcd(a,n)=1\gcd(a, n) = 1, we also have gcd(amq,n)=1\gcd\bigl(a^{mq}, n\bigr) = 1. Hence n(ar1)n \mid \bigl(a^{r} - 1\bigr), i.e.

ar1(modn).a^{r} \equiv 1 \pmod{n}.

But mm is the least positive integer with this property and 0r<m0 \le r < m, so r=0r = 0. Thus mkm \mid k.

Apply this with a=2a = 2 and n=37n = 37. Fermat already gave 2361(mod37)2^{36} \equiv 1 \pmod{37}, so ord37(2)36\operatorname{ord}_{37}(2) \mid 36. The positive divisors of 3636 are 1,2,3,4,6,9,12,18,361, 2, 3, 4, 6, 9, 12, 18, 36. It remains to check that none of the proper ones works:

m2mmod3712243841662793112261836\begin{array}{c|c} m & 2^{m} \bmod 37 \\ \hline 1 & 2 \\ 2 & 4 \\ 3 & 8 \\ 4 & 16 \\ 6 & 27 \\ 9 & 31 \\ 12 & 26 \\ 18 & 36 \end{array}

None of these is 11. Therefore ord37(2)=36\operatorname{ord}_{37}(2) = 36, and

2i/2j(mod37)for all 0i<j35.2^{i} \nequiv 2^{j} \pmod{37} \qquad \text{for all } 0 \le i < j \le 35.

No collisions.