It can be solved using a combination and permutation methods.
F (N) = rank
First, find the number of bits that should represent N. In binary, a number can be constructed as follows:
N = cn 2^n + .... + c3 2^2 + c2 2^1 + c1 2^0
Now, to find n (or the number of bits in the binary representation of the number) in the above equation, we can assume that it will be floor(log2(N)) + 1 . For example, consider any number, say 118 , then it can be represented by gender (log2 (118)) + 1 = 7 bits.
n = floor(log2(118)) + 1;
Above the formula is only O(1) . Now we need to find how many 1s exist in the binary representation of the number. Given the pseudo code to complete this task:
function count1(int N) { int c = 0; int N' = N; while(N' > 0) { N' -= 2^(floor(log2(N'))); c++; } }
Above the pseudo code is O(logN) . I wrote a small script in MATLAB to check my pseudo code above and here are the results.
count1(6) = 2 count1(3) = 2 count1(118) = 5
Perfectly, now we have the number of bits and the number 1s in these bits. Now, to find the rank of a number, you can apply a simple combination and permutation. first suppose that n is the number of bits needed to represent the number, and c is the number 1 in the bit representation of the number. Therefore, the rank will be set as follows:
r = n ! / c ! * (n - c) !
EDIT: As suggested by DSM, I corrected the logic to find the correct RANK. The idea is to remove all unnecessary numbers from the permutation. So added this code:
for i = N + 1 : 2^n - 1 if count(i) == c r = r - 1; end end
I wrote a MATLAb script to find the rank of a number using the method described above:
function r = rankN(N) n = floor(log2(N)) + 1; c = count(N); r = factorial(n) / (factorial(c) * factorial(n - c)); % rejecting all the numbers may have included in the permutations % but are unnecessary. for i = N + 1 : 2^n - 1 if count(i) == c r = r - 1; end end function c = count(n) c = 0; N = n; while N > 0 N = N - 2^(floor(log2(N))); c = c + 1; end
And above alogrithm O(1) + O(logN) + O(1) = O(logN) . Exit:
>> rankN(3) ans = 1 >> rankN(4) ans = 3 >> rankN(7) ans = 1 >> rankN(118) ans = 18 >> rankN(6) ans = 3
Note. Rank 0 always 1 , because the method above will not work for 0 , because log2(0) is undefined.