How to find the nth binary permutation? - permutation

This is the last missing piece I need to complete my compression algorithm, new one. Let's say I have 4 bits with 2 bits set as 1, 0011. The total number of permutations for this number is 0011, 0101, 0110, 1001, 1010, 1100, 6 cases. This can be computed using the calculation.
4! / ((2!)(4-2)!) = 6
Now I want to be able to find the nth sequence, for instance 1st number is 0011, second number is 0101. So if I say n=5, I want to be able to get the 5th permutation sequence 1010 from the initial 0011. How do I do this?

If there are only two 1 in the binary, it's not too difficult.
When the highest 1 bit locate at x position, the number of permutation is x.
So that, the highest bit position is the smallest a (starts from 0), subjecting to a*(a+1)/2 >= n. You can easily find a by a O(n) loop.
Then the least bit position is a*(a+1)/2-n (starts from 0)
For example, when n is 5, the smallest a is 3, and the least bit position is 1, so that the answer is 1010

Related

DFA for binary numbers that have a remainder of 1 when divided by 3

I need a DFA for a set of all strings beginning with a 1 that, interpreted as the binary representation of an integer, have a remainder of 1 when divided by 3.
For example, the binary number 1010 b is decimal 10. When you divide 10 by 3 you get a remainder of 1, so 1010 is in the language. However, the binary number 1111 b is decimal 15. When you divide 15 by 3 you get a remainder of 0, so 1111 is not in the language.
I've attached my DFA below. Could you please check it?
It looks correct to me.
You could make two simplifications:
q4 represents (mod 0), so you could make it the starting state and get rid of q0 and q5. (Unless you are required to reject strings beginning with a 0? Your question doesn't specify.)
q1 and q3 can be merged. They both represent (mod 1) and have the same transitions.
These two changes would leave you with exactly 3 states, one for each remainder.

Find amount of natural numbers generated from array of digit characters

Good day.
I have an array of digit characters ['9','0'] or ['9','5','2','0','0','0']. Need to find amount of all natural numbers with length equal to array size generated from a source array. For example for ['9','0'] it will be only 90 and answer is 1.
If array has no 0 and digits duplication amount of numbers can be calculated by factorial:
['5','7','2'] => 3! => 6
['1','2','3','4','5','6','7'] => 7! => 5040.
When zeros and duplication appears it's become changeable.
More examples: https://www.codewars.com/kumite/5a26eb9ab6486ae2680000fe?sel=5a26eb9ab6486ae2680000fe
Thank you
P.S. Better to find formula, I know how solve this problem by loops
def g(a)
answer = a.permutation(a.size)
.select{|x| x.join.to_i.to_s.split("").size == a.size }.to_a.uniq.size
answer
end
The only difference with '0' is that you can't have leading '0', aka first digit cannot be 0.
The formula given an array of N numbers become
(N - Number of zeros) * (N-1)!
When there is no zero, it is just N!.
Now consider the case with duplication, lets say there are K '1' in the array. For every permutation you have in the previous calculation, you can swap the '1' in K! permutation, thus you need to divide your result with K!. This need to be done for every single digits with duplicates. When there is no duplication (0 or 1 such digit), you are dividing by 0! or 1! thus division does not change the value.
Sample case: [0, 0, 1, 1]
4 digits, 2 zeros, 2 ones
(4-2) * 3! / (2! * 2!) = 3
Possible permutation: 1001, 1010, 1100

Possible values for operands in bitwise-and expression

Given the following C code:
int x = atoi(argv[1]);
int y = (x & -x);
if (x==y)
printf("Wow... they are the same!\n");
What values of x will result in "Wow... they are the same!" getting printed? Why?
So. It generally depends, but I can assume, that your architecture represents numbers with sign in U2 format (everything is false if it's not in U2 format). Let's have an example.
We take 3, which representation will be like:
0011
and -3. which will be:
~ 0011
+ 1
-------
1101
and we make and
1101
& 0011
------
0001
so:
1101 != 0001
that's what is happening underhood. You have to find numbers that fit to this pattern. I do not know what kind of numbers fit it upfront. But basing on this you can predict this.
The question is asking about the binary & operator, and 2's compliment arithmetic.
I would look to how numbers are represented in 2's compliment, and what the binary & symbol does.
Assuming a 2's compliment representation for negative numbers, the only values for which this is true are positive numbers of the form 2^n where n >= 0, and 0.
When you take the 2's compliment of a number, you flip all bits and then add one. So the least significant bit will always match. The next bit won't match unless the prior carried over, and the same for the next bit.
An int is typically 32 bits, however I'll use 5 bits in the following examples for simplicity.
For example, 5 is 00101. Flipping all bits gives us 11010, then adding 1 gives us 11011. Then 00101 & 11011 = 00001. The only bit that matches a set bit is the last one, so 5 doesn't work.
Next we'll try 12, which is 01100. Flipping the bits gives us 10011, then adding 1 gives us 10100. Then 01100 & 10100 = 00100. Because of the carry-over the third bit is set, however the second bit is not, so 12 doesn't work either.
So the most significant bit which is set won't match unless all lower bits carry over when 1 is added. This is true only for numbers with one bit set, i.e. powers of 2.
If we now try 8, which is 01000, flipping the bits gives us 10111 and adding 1 gives us 11000. And 01000 & 11000 = 01000. In this case, the second bit is set, which is the only bit set in the original number. So the condition holds.
Negative numbers cannot satisfy this condition because positive numbers have the most significant bit set to 0, while negative numbers have the most significant bit set to 1. So a bitwise AND of a number and its negative will always have the most significant bit set to 0, meaning this number cannot be negative.
0 is a special case since it is its own negative. 0 & 0 = 0, so it also satisfies this condition.
Another special case is the smallest number you can represent. In the case of a 5-bit number this is -16, which is represented by 10000. Flipping all the bits gives you 01111 and adding 1 gives you 10000, which is the same number. On the surface it seems this number also satisfies the condition, however this is an overflow condition and implementations may not handle this case correctly. See this link for more details.

GROUPING_ID functionality

I don't quite understand how this function works, I've been looking over the below documentation, and I have some issues.
http://msdn.microsoft.com/en-us/library/bb510624.aspx
So, I understand how GROUPING() works perfectly, but the output for GROUPING_ID is quite impossible for me to comprehend how it's done because it's not the same with the explanation.
For example I have the following string of ones and zeroes: 010. In the documentation it says it's equal to 2. Also I read in a SQL book that each byte (the rightmost) is EQUAL with 2 at the power of the byte position minus one.
So, (2^2 - 1) + (2^1 - 1 ) + (2^0 - 1), but isn't that the same for each binary number? (100/101/110/etc), and the result isn't 2 either....
EDIT 1 :
This is how the explanation from the book is:
Another function that you can use to identify the grouping sets is GROUPING_ID. This
function accepts the list of grouped columns as inputs and returns an integer representing a
bitmap. The rightmost bit represents the rightmost input. The bit is 0 when the respective element
is part of the grouping set and 1 when it isn’t. Each bit represents 2 raised to the power
of the bit position minus 1; so the rightmost bit represents 1, the one to the left of it 2, then 4,
then 8, and so on. The result integer is the sum of the values representing elements that are
not part of the grouping set because their bits are turned on. Here’s a query demonstrating
the use of this function.
There has to be an error because there is no way a number is calculated by 2^(position) - 1, is it a mistake ? I've been calculating with 2^(bitposition) *1 and the outputs are correct.
For example the I've done this
GROUPING_ID(a,b,c),
GROUPING(a),
GROUPING(b),
GROUPING(c)
And let's say we have the following output
3, 0, 1, 1
So our binary string is 011 and 3 is the output of the GROUPING_ID function, if we calculate the string
2^0 * 1 + 2^1 * 1 + 2^0 *2 = 1 + 2 + 0 = 3
There is no other logic that I see here, I cannot calculate with minus as the upper quote says, the thing is that on MSDN the weirder definition seems to be somewhat similar with this one:
Each GROUPING_ID argument must be an element of the GROUP BY list. GROUPING_ID () returns an integer bitmap whose lowest N bits may be lit.
A lit bit indicates the corresponding argument is not a grouping column for the given output row. The lowest-order bit corresponds to argument N, and the N-1th lowest-order bit corresponds to argument 1.
First of all, when they say
Each bit represents 2 raised to the power of the bit position minus 1
they do not mean 2position - 1 but rather 2position - 1. Apparently, for the purpose of their description they chose to count bits from 1 (for the rightmost bit) rather than from 0.
Secondly, each bit represents the said value when it is set, i.e. when it is 1. So, naturally, you do not do just
21 - 1 + 22 - 1 + ... + 2N - 1
but rather
bit1 × 21 - 1 + bit2 × 22 - 1 + ... + bitN × 2N - 1
which is the normal way of converting the binary representation to the decimal one and is also the method you have shown near the end of your question.
Lets say we have binary number 0101
we went from right to left
1->(2^0*1)=1
0->(2^1*0)=0
1->(2^2*1)=4
0->(2^3*0)=0
if we summerize all results we have 5
so 0101(binary)=5(decimal)

Find the missing number in a group {0......2^k -1} range

Given an array that has the numbers {0......2^k -1} except for one number ,
find a good algorithm that finds the missing number.
Please notice , you can only use :
for A[i] return the value of bit j.
swap A[i] with A[j].
My answer : use divide & conquer , check the bit number K of all the numbers , if the K bit (now we're on the LSB) is 0 then move the number to the left side, if the K bit is 1 then move the number to the right side.
After the 1st iteration , we'd have two groups , where one of them is bigger than the other , so we continue to do the same thing, with the smaller group , and I think that I need to check the K-1 bit this time.
But from some reason I've tried with 8 numbers , from 0.....7 , and removed 4 (say that I want to find out that 4 is the missing number) , however to algorithm didn't work out so good. So where is my mistake ?
I assume you can build xor bit function using get bit j.
The answer will be (xor of all numbers)
PROOF: a xor (2^k-1-a) = 2^k-1 (a and (2^k-1-a) will have different bits in first k positions).
Then 0 xor 1 xor ... xor 2^k-1 = (0 xor 2^k-1) xor (1 xor 2^k-2).... (2^(k-1) pairs) = 0.
if number n is missing the result will be n, because 0 xor 1 xor 2....xor n-1 xor n+1 xor ... = 0 xor 1 xor 2....xor n-1 xor n+1 xor ... xor n xor n = 0 xor n = n
EDIT: This will not work if k = 1.
Ron,
your solution is correct. This problem smells Quicksort, doesn't it ?
What you do with the Kth bit (all 0's to the left, 1's to the right) is a called a partition - you need to find the misplaced elements in pairs and swap them. It's the process used in Hoare's Selection and in Quicksort, with special element classification - no need to use a pivot element.
You forgot to tell in the problem statement how many elements there are in the array (2^k-2 or more), i.e. if repetitions are allowed.
If repetitions are not allowed, every partition will indeed be imbalanced by one element. The algorithm to use is an instance of Hoare's Selection (only partition the smallest halve). At every partition stage, the number of elements to be considered is halved, hence O(N) running time. This is optimal since every element needs to be known before the solution can be found.
[If repetitions are allowed, use modified Quicksort (recursively partition both halves) until you arrive at an empty half. The running time is probably O(N Lg(N)) then, but this needs to be checked.]
You say that the algorithm failed on your test case: you probably mis-implemented some detail.
An example:
Start with
5132670 (this is range {0..7})
After partitioning on bit weight=4 you get
0132|675
where the shortest half is
675 (this is range {4..7})
After partitioning on bit weight=2, you get
5|67
where the shortest half is
5 (this is range {4..5})
After partitioning on bit weight=1, you get
|5
where the shortest half is empty (this is range {4}).
Done.
for n just add them all and subtract the result from n*(n+1)/2
n*(n+1)/2 is sum of 1...n all numbers. If one of them is missing, then sum of those n-1 numbers will be n*(n+1)/2-missingNumber
Your answer is: n*(n+1)/2-missingNumber where n is 2^k-1
Given the fact that for a given bit position j, there are exactly 2^(k-1) numbers which have it set to 0, and 2^(k-1) which have it set to 1 use the following algorithm.
start with an array B of boolean of size k
init the array to false everywhere
for each number A[i]
for each position j
get the value v
if v is 1 invert the boolean at position j
end for
end for
If a position is false at the end then the missing number does have a zero at
this position, otherwise it has a one (for k >1, If k = 1 then it is the inverse). Now to implement your array of booleans
create a number of size 2k, where the lower k are set to 0, and the upper
are set to 1. Then
invert the boolean at position j
is simply *
swap B[j] with B[j+k].
With this representation the missing number is the lower k elements of the array
B. Well this algorithm is still O(k*2^k) but you can say it is O(n*log(n))
of the input.
you can consider elements as string of k bits and at each step i if the number of ones or zeros in position i is 2^(k-i) you should remove all those strings an continue for example
100 111 010
101 110 000 011
so
100 111 101 110 all will be removed
and between 010 000 011 , 010 and 011 will be removed because their second bit is 1
000 remain and its rightmost bit is zero so 001 is the missing number

Resources