Find XOR of all numbers in a given range - algorithm

You are given a large range [a,b] where 'a' and 'b' can be typically between 1 and 4,000,000,000 inclusive. You have to find out the XOR of all the numbers in the given range.
This problem was used in TopCoder SRM. I saw one of the solutions submitted in the match and I'm not able to figure out how its working.
Could someone help explain the winning solution:
long long f(long long a) {
long long res[] = {a,1,a+1,0};
return res[a%4];
}
long long getXor(long long a, long long b) {
return f(b)^f(a-1);
}
Here, getXor() is the actual function to calculate the xor of all number in the passed range [a,b] and "f()" is a helper function.

This is a pretty clever solution -- it exploits the fact that there is a pattern of results in the running XORs. The f() function calculates the XOR total run from [0, a]. Take a look at this table for 4-bit numbers:
0000 <- 0 [a]
0001 <- 1 [1]
0010 <- 3 [a+1]
0011 <- 0 [0]
0100 <- 4 [a]
0101 <- 1 [1]
0110 <- 7 [a+1]
0111 <- 0 [0]
1000 <- 8 [a]
1001 <- 1 [1]
1010 <- 11 [a+1]
1011 <- 0 [0]
1100 <- 12 [a]
1101 <- 1 [1]
1110 <- 15 [a+1]
1111 <- 0 [0]
Where the first column is the binary representation and then the decimal result and its relation to its index (a) into the XOR list. This happens because all the upper bits cancel and the lowest two bits cycle every 4. So, that's how to arrive at that little lookup table.
Now, consider for a general range of [a,b]. We can use f() to find the XOR for [0,a-1] and [0,b]. Since any value XOR'd with itself is zero, the f(a-1) just cancels out all the values in the XOR run less than a, leaving you with the XOR of the range [a,b].

Adding to FatalError's great answer, the line return f(b)^f(a-1); could be explained better. In short, it's because XOR has these wonderful properties:
It's associative - Place brackets wherever you want
It's commutative - that means you can move the operators around (they can "commute")
Here's both in action:
(a ^ b ^ c) ^ (d ^ e ^ f) = (f ^ e) ^ (d ^ a ^ b) ^ c
It reverses itself
Like this:
a ^ b = c
c ^ a = b
Add and multiply are two examples of other associative/ commutative operators, but they don't reverse themselves. Ok, so, why are these properties important? Well, a simple route is to expand it out into what it really is, and then you can see these properties at work.
First, let's define what we want and call it n:
n = (a ^ a+1 ^ a+2 .. ^ b)
If it helps, think of XOR (^) as if it was an add.
Let's also define the function:
f(b) = 0 ^ 1 ^ 2 ^ 3 ^ 4 .. ^ b
b is greater than a, so just by safely dropping in a few extra brackets (which we can because it's associative), we can also say this:
f(b) = ( 0 ^ 1 ^ 2 ^ 3 ^ 4 .. ^ (a-1) ) ^ (a ^ a+1 ^ a+2 .. ^ b)
Which simplifies to:
f(b) = f(a-1) ^ (a ^ a+1 ^ a+2 .. ^ b)
f(b) = f(a-1) ^ n
Next, we use that reversal property and commutivity to give us the magic line:
n = f(b) ^ f(a-1)
If you've been thinking of XOR like an add, you would've dropped in a subtract there. XOR is to XOR what add is to subtract!
How do I come up with this myself?
Remember the properties of logical operators. Work with them almost like an add or multiply if it helps. It feels unusual that and (&), xor (^) and or (|) are associative, but they are!
Run the naive implementation through first, look for patterns in the output, then start finding rules which confirm the pattern is true. Simplify your implementation even further and repeat. This is probably the route that the original creator took, highlighted by the fact that it's not completely optimal (i.e. use a switch statement rather than an array).

I found out that the below code is also working like the solution given in the question.
May be this is little optimized but its just what I got from observing repetition like given in the accepted answer,
I would like to know / understand the mathematical proof behind the given code, like explained in the answer by #Luke Briggs
Here is that JAVA code
public int findXORofRange(int m, int n) {
int[] patternTracker;
if(m % 2 == 0)
patternTracker = new int[] {n, 1, n^1, 0};
else
patternTracker = new int[] {m, m^n, m-1, (m-1)^n};
return patternTracker[(n-m) % 4];
}

I have solved the problem with recursion. I simply divide the dataset into an almost equal part for every iteration.
public int recursion(int M, int N) {
if (N - M == 1) {
return M ^ N;
} else {
int pivot = this.calculatePivot(M, N);
if (pivot + 1 == N) {
return this.recursion(M, pivot) ^ N;
} else {
return this.recursion(M, pivot) ^ this.recursion(pivot + 1, N);
}
}
}
public int calculatePivot(int M, int N) {
return (M + N) / 2;
}
Let me know your thoughts over the solution. Happy to get improvement feedbacks. The proposed solution calculates the XOR in 0(log N) complexity.
Thank you

To support XOR from 0 to N the code given needed to be modified as below,
int f(int a) {
int []res = {a, 1, a+1, 0};
return res[a % 4];
}
int getXor(int a, int b) {
return f(b) ^ f(a);
}

Adding on even further to FatalError's answer, it's possible to prove (by induction) that the observed pattern in f() will cycle for every 4 numbers.
We're trying to prove that for every integer k >= 0,
f(4k + 1) = 1
f(4k + 2) = 4k + 3
f(4k + 3) = 0
f(4k + 4) = 4k + 4
where f(n) is 1 ^ 2 ^ ... ^ n.
As our base case, we can work out by hand that
f(1) = 1
f(2) = 1 ^ 2 = 3
f(3) = 3 ^ 3 = 0
f(4) = 0 ^ 4 = 4
For our inductive step, assume that these equations are true up to a particular integer 4x (i.e. f(4x) = 4x). We want to show that our equations are true for 4x + 1, 4x + 2, 4x + 3 and 4x + 4.
To help write and visualize the proof, we can let b(x) denote the binary (base-2) string representation of x, for example
b(7) = '111', b(9) = '1001'.
and
b(4x) = 'b(x)00'
b(4x + 1) = 'b(x)01'
b(4x + 2) = 'b(x)10'
b(4x + 3) = 'b(x)11'
Here is the inductive step:
Assume: f(4x) = 4x = 'b(x)00'
Then:
f(4x + 1) = f(4x) ^ (4x + 1) // by definition
= f(4x) ^ 'b(x)01' // by definition
= 'b(x)00' ^ 'b(x)01' // from assumption
= '01' // as b(x) ^ b(x) = 0
f(4x + 2) = f(4x + 1) ^ (4x + 2)
= f(4x + 1) ^ 'b(x)10'
= '01' ^ 'b(x)10'
= 'b(x)11' // this is 4x + 3
f(4x + 3) = f(4x + 2) ^ (4x + 3)
= f(4x + 2) ^ 'b(x)11'
= 'b(x)11' ^ 'b(x)11'
= '00'
For the last case, we don't use binary strings,
since we don't know what b(4x + 4) is.
f(4x + 4) = f(4x + 3) ^ (4x + 4)
= 0 ^ (4x + 4)
= 4x + 4
So the pattern holds for the next four numbers after 4x, completing the proof.

Related

Select elements in a sequence

Consider the following problem:
I have sequence with 2q elements {a[1], ..., a[2q]}, which has been sorted. Then I need to get two sub-sequences b[i] and c[i], which satisfy:
Both b[i] and c[i] have q elements and Join({b[i]}, {c[i]}) = {a[i]}
b[1] < b[2] < ... < b[q]
b[i] < c[i] for all i = 1...q
The difficulty is that I want to get all sequence that satisfy the conditions. How can I do that?
The first step is to partition the input into two halves, while making sure that each partition will lead to a solution. We can do that with a simple recursive method:
Iterate over the input from small to large; for each element, choose whether it goes into subsequence b or c, using these rules:
If b and c have the same length, add the element to b.
if b is longer than c, add the element once to b and once to c and recurse with both options.
If b is full, add all elements to c.
This will give us a number if different partitions, e.g. for the input [1,2,3,4,5,6] they would be:
[1,2,3],[4,5,6]
[1,2,4],[3,5,6]
[1,2,5],[3,4,6]
[1,3,4],[2,5,6]
[1,3,5],[2,4,6]
Then, for each of these partitions, we have to find the permutations of c which meet the conditions. Again, a simple recursive method will do the trick:
Iterate over b from right to left. For each element, find the elements in c which are greater. If there is only one, put it in the corresponding location in c. If there are severeal, put each of the elements in the corresponding location in c once, and recurse with each option.
For the partition [1,2,4],[3,5,6] in the example, that would lead to:
[1,2,4],[x,x,x] <- (3,5,6) ... [1,2,4],[x,x,6] <- (3,5) ... [1,2,4],[3,5,6]
^ ^ ^ ^ ^ ^
... [1,2,4],[x,x,6] <- (3,5) ... [1,2,4],[5,3,6]
^ ^ ^
[1,2,4],[x,x,x] <- (3,5,6) ... [1,2,4],[x,x,5] <- (3,6) ... [1,2,4],[3,6,5]
^ ^ ^ ^ ^ ^
... [1,2,4],[x,x,5] <- (3,6) ... [1,2,4],[6,3,5]
^ ^ ^
This code example is a straightforward implementation of the algorithm explained above:
function subsequences(a) {
var q = a.length / 2;
partition(0, [], []);
function partition(pos, part1, part2) {
var b = part1.slice(); // create copy
var c = part2.slice(); // create copy
if (b.length == c.length) {
b.push(a[pos++]);
}
while (b.length < q) {
c.push(a[pos++]);
partition(pos, b, c);
b.push(c.pop());
}
while (c.length < q) {
c.push(a[pos++]);
}
permute(b, [], c);
}
function permute(b, part, set) {
var pos = set.length - 1;
for (var i = pos; i >= 0 && set[i] > b[pos]; i--) {
var c = part.slice(); // create copy
var s = set.slice(); // create copy
c[pos] = s.splice(i, 1);
if (pos == 0) { // store or process subsequences
document.write("{" + b + "},{" + c + "}<br>");
}
else permute(b, c, s);
}
}
}
subsequences([1,2,3,4,5,6,7,8,9,10,11,12]); // ascending order
The algorithm finds the following number of valid partitions, and valid permutations of c. (For comparison, I've added the number of all partitions and all permutations that a naive solution would need to generate and then check.)
q partitions permutations | all part. all perm.
|
1 1 1 | 1 1
2 2 3 | 3 6
3 5 15 | 10 60
4 14 105 | 35 840
5 42 945 | 126 15,120
6 132 10,395 | 462 332,640
7 429 135,135 | 1,716 8,648,640
8 1,430 2,027,025 | 6,435 259,459,200
9 4,862 34,459,425 | 24,310 8,821,612,800
10 16,796 654,729,075 | 92,378 335,221,286,400
Running only the first part of the algorithm, we find that for q=20, the number of valid partitions is 6,564,120,420, and the number of valid permutations is probably around 1022.
NOTES:
For the partition function to work correctly, the input sequence needs to be in ascending order. In the permute function, the set of unused values in subsequence c is also kept in ascending order, to make it easier to find the largest values.
The results for any input sequence of n numbers will be similar. In fact, you can replace the input sequence by [0,1,2,3 ... n-1] and then use the values in the results as indexes in the original input sequence. This means that if you need the results for different sequences of n numbers, you only need to run the algorithm once.

Querying in a range[L,R]

Given a binary string (that is a string consisting of only 0 and 1). They were supposed to perform two types of query on the string.Problem
Type 0: Given two indices l and r.Print the value of the binary string from l to r modulo 3.
Type 1: Given an index l flip the value of that index if and only if the value at that index is 0.
I am trying to solve this using BIT.
If the number in range [l,r] is even then:
if the sum of the numbers of one is even then the answer is 0 else 2
If the number in range [l,r] is odd
if the sum of the numbers of one is even then the answer is 0 else 1
But I am getting wrong answer for some test cases what wrong is in my approach.
public static void update(int i){
while(A.length>i){
A[i]+=1;
i+=i&-i;
}
}
public static int ans(int i){
int a=0;
while(i>0){
a+=A[i];
i-=i&-i;
}
return a;
}
Answer for each Query.
while(Q>0){
Q--;
int x = in.nextInt();
int l = in.nextInt()+1;
if(x==1){
if((ans(l)-ans(l-1))==0) update(l);
continue;
}
int r = in.nextInt()+1;
int f = ans(r) - ans(r-1);
if(f==0){
int sum = ans(r)- ans(l-1);
if(sum%2==0) System.out.println(0);
else System.out.println(2);
}else{
int sum = ans(r)- ans(l-1);
if(sum%2==0) System.out.println(0);
else System.out.println(1);
}
}
Full CODE
When building a binary number, from the left digit to the right digit, if you consider only a currently parsed section of the string, it is a binary number. We'll call it n.
When you append a digit to the right of n, this shifts it left, and then also adds the digit (1 or 0). So n0 = 2*n and n1 = 2*n+1
Because you only care about the number modulo 3, you can just keep track of this modulo 3.
You can note that
0 (mod 3) * 2 = 0 (mod 3)
0 (mod 3) * 2 + 1 = 1 (mod 3)
1 (mod 3) * 2 = 2 (mod 3)
1 (mod 3) * 2 + 1 = 0 (mod 3)
2 (mod 3) * 2 = 1 (mod 3)
2 (mod 3) * 2 + 1 = 2 (mod 3)
You can construct a simple fsm to represent these relationships and simply use the section of the string which you are interested in as input to it. Or implement it however else you want.
Hopefully you realise that "Given an index l flip the value of that index if and only if the value at that index is 0." simply means set the value at l to 1.

Intuition behind this solution for "Maximising XOR"

Here is the problem statement:
Given two integers: L and R,
find the maximal values of A xor B given, L ≤ A ≤ B ≤ R
Input Format:
The input contains two lines, L is present in the first line.
R in the second line.
Constraints :
1 ≤ L ≤ R ≤ 1000
Output Format
The maximal value as mentioned in the problem statement.
Source:
Maximising XOR
Here is one unique solution to the above:
def maxXOR(L,R):
P = L^R
ret = 1
while(P): # this one takes (m+1) = O(logR) steps
ret <<= 1
P >>= 1
return (ret - 1)
print(maxXOR(int(input()),int(input())))
Could you please explain the intuition behind this solution?
Thank you.
There is one simple way using which you can solve the problem in O(1).
Let's start:
Do the bit-wise XOR of L and R and store it in a variable say xored.
Then take the MSB in the xored which is set and make all the bits from that MSB -----> LSB as 1 and that is the answer.
Following example which will make things clear.
L = 10111 --> (23)
R = 11100 --> (28)
_X___ <-- that's most significant differing bit
01111 <-- here's our final answer i.e. (15).
To set all the bits from MSB to LSB, first calculate the 2^n - 1 where n = number of bits required to represent L^R and then do L^R | (2^(n) - 1).
Solution in Python:
import math
def main():
xored = int(input().strip()) ^ int(input().strip())
print("{}".format(xored | ((1 << (1 + int(math.log2(xored)))) - 1)))
if __name__ == "__main__":
main()
NOTE: You can refer to solution in C and C++ here!.

Find number of binary numbers with certain constraints

This is more of a puzzle than a coding problem. I need to find how many binary numbers can be generated satisfying certain constraints. The inputs are
(integer) Len - Number of digits in the binary number
(integer) x
(integer) y
The binary number has to be such that taking any x adjacent digits from the binary number should contain at least y 1's.
For example -
Len = 6, x = 3, y = 2
0 1 1 0 1 1 - Length is 6, Take any 3 adjacent digits from this and
there will be 2 l's
I had this C# coding question posed to me in an interview and I cannot figure out any algorithm to solve this. Not looking for code (although it's welcome), any sort of help, pointers are appreciated
This problem can be solved using dynamic programming. The main idea is to group the binary numbers according to the last x-1 bits and the length of each binary number. If appending a bit sequence to one number yields a number satisfying the constraint, then appending the same bit sequence to any number in the same group results in a number satisfying the constraint also.
For example, x = 4, y = 2. both of 01011 and 10011 have the same last 3 bits (011). Appending a 0 to each of them, resulting 010110 and 100110, both satisfy the constraint.
Here is pseudo code:
mask = (1<<(x-1)) - 1
count[0][0] = 1
for(i = 0; i < Len-1; ++i) {
for(j = 0; j < 1<<i && j < 1<<(x-1); ++j) {
if(i<x-1 || count1Bit(j*2+1)>=y)
count[i+1][(j*2+1)&mask] += count[i][j];
if(i<x-1 || count1Bit(j*2)>=y)
count[i+1][(j*2)&mask] += count[i][j];
}
}
answer = 0
for(j = 0; j < 1<<i && j < 1<<(x-1); ++j)
answer += count[Len][j];
This algorithm assumes that Len >= x. The time complexity is O(Len*2^x).
EDIT
The count1Bit(j) function counts the number of 1 in the binary representation of j.
The only input to this algorithm are Len, x, and y. It starts from an empty binary string [length 0, group 0], and iteratively tries to append 0 and 1 until length equals to Len. It also does the grouping and counting the number of binary strings satisfying the 1-bits constraint in each group. The output of this algorithm is answer, which is the number of binary strings (numbers) satisfying the constraints.
For a binary string in group [length i, group j], appending 0 to it results in a binary string in group [length i+1, group (j*2)%(2^(x-1))]; appending 1 to it results in a binary string in group [length i+1, group (j*2+1)%(2^(x-1))].
Let count[i,j] be the number of binary strings in group [length i, group j] satisfying the 1-bits constraint. If there are at least y 1 in the binary representation of j*2, then appending 0 to each of these count[i,j] binary strings yields a binary string in group [length i+1, group (j*2)%(2^(x-1))] which also satisfies the 1-bit constraint. Therefore, we can add count[i,j] into count[i+1,(j*2)%(2^(x-1))]. The case of appending 1 is similar.
The condition i<x-1 in the above algorithm is to keep the binary strings growing when length is less than x-1.
Using the example of LEN = 6, X = 3 and Y = 2...
Build an exhaustive bit pattern generator for X bits. A simple binary counter can do this. For example, if X = 3
then a counter from 0 to 7 will generate all possible bit patterns of length 3.
The patterns are:
000
001
010
011
100
101
110
111
Verify the adjacency requirement as the patterns are built. Reject any patterns that do not qualify.
Basically this boils down to rejecting any pattern containing fewer than 2 '1' bits (Y = 2). The list prunes down to:
011
101
110
111
For each member of the pruned list, add a '1' bit and retest the first X bits. Keep the new pattern if it passes the
adjacency test. Do the same with a '0' bit. For example this step proceeds as:
1011 <== Keep
1101 <== Keep
1110 <== Keep
1111 <== Keep
0011 <== Reject
0101 <== Reject
0110 <== Keep
0111 <== Keep
Which leaves:
1011
1101
1110
1111
0110
0111
Now repeat this process until the pruned set is empty or the member lengths become LEN bits long. In the end
the only patterns left are:
111011
111101
111110
111111
110110
110111
101101
101110
101111
011011
011101
011110
011111
Count them up and you are done.
Note that you only need to test the first X bits on each iteration because all the subsequent patterns were verified in prior steps.
Considering that input values are variable and wanted to see the actual output, I used recursive algorithm to determine all combinations of 0 and 1 for a given length :
private static void BinaryNumberWithOnes(int n, int dump, int ones, string s = "")
{
if (n == 0)
{
if (BinaryWithoutDumpCountContainsnumberOfOnes(s, dump,ones))
Console.WriteLine(s);
return;
}
BinaryNumberWithOnes(n - 1, dump, ones, s + "0");
BinaryNumberWithOnes(n - 1, dump, ones, s + "1");
}
and BinaryWithoutDumpCountContainsnumberOfOnes to determine if the binary number meets the criteria
private static bool BinaryWithoutDumpCountContainsnumberOfOnes(string binaryNumber, int dump, int ones)
{
int current = 0;
int count = binaryNumber.Length;
while(current +dump < count)
{
var fail = binaryNumber.Remove(current, dump).Replace("0", "").Length < ones;
if (fail)
{
return false;
}
current++;
}
return true;
}
Calling BinaryNumberWithOnes(6, 3, 2) will output all binary numbers that match
010011
011011
011111
100011
100101
100111
101011
101101
101111
110011
110101
110110
110111
111011
111101
111110
111111
Sounds like a nested for loop would do the trick. Pseudocode (not tested).
value = '0101010111110101010111' // change this line to format you would need
for (i = 0; i < (Len-x); i++) { // loop over value from left to right
kount = 0
for (j = i; j < (i+x); j++) { // count '1' bits in the next 'x' bits
kount += value[j] // add 0 or 1
if kount >= y then return success
}
}
return fail
The naive approach would be a tree-recursive algorithm.
Our recursive method would slowly build the number up, e.g. it would start at xxxxxx, return the sum of a call with 1xxxxx and 0xxxxx, which themselves will return the sum of a call with 10, 11 and 00, 01, etc. except if the x/y conditions are NOT satisfied for the string it would build by calling itself it does NOT go down that path, and if you are at a terminal condition (built a number of the correct length) you return 1. (note that since we're building the string up from left to right, you don't have to check x/y for the entire string, just also considering the newly added digit!)
By returning a sum over all calls then all of the returned 1s will pool together and be returned by the initial call, equalling the number of constructed strings.
No idea what the big O notation for time complexity is for this one, it could be as bad as O(2^n)*O(checking x/y conditions) but it will prune lots of branches off the tree in most cases.
UPDATE: One insight I had is that all branches of the recursive tree can be 'merged' if they have identical last x digits so far, because then the same checks would be applied to all digits hereafter so you may as well double them up and save a lot of work. This now requires building the tree explicitly instead of implicitly via recursive calls, and maybe some kind of hashing scheme to detect when branches have identical x endings, but for large length it would provide a huge speedup.
My approach is to start by getting the all binary numbers with the minimum number of 1's, which is easy enough, you just get every unique permutation of a binary number of length x with y 1's, and cycle each unique permutation "Len" times. By flipping the 0 bits of these seeds in every combination possible, we are guaranteed to iterate over all of the binary numbers that fit the criteria.
from itertools import permutations, cycle, combinations
def uniq(x):
d = {}
for i in x:
d[i]=1
return d.keys()
def findn( l, x, y ):
window = []
for i in xrange(y):
window.append(1)
for i in xrange(x-y):
window.append(0)
perms = uniq(permutations(window))
seeds=[]
for p in perms:
pr = cycle(p)
seeds.append([ pr.next() for i in xrange(l) ]) ###a seed is a binary number fitting the criteria with minimum 1 bits
bin_numbers=[]
for seed in seeds:
if seed in bin_numbers: continue
indexes = [ i for i, x in enumerate(seed) if x == 0] ### get indexes of 0 "bits"
exit = False
for i in xrange(len(indexes)+1):
if( exit ): break
for combo in combinations(indexes, i): ### combinatorically flipping the zero bits in the seed
new_num = seed[:]
for index in combo: new_num[index]+=1
if new_num in bin_numbers:
### if our new binary number has been seen before
### we can break out since we are doing a depth first traversal
exit=True
break
else:
bin_numbers.append(new_num)
print len(bin_numbers)
findn(6,3,2)
Growth of this approach is definitely exponential, but I thought I'd share my approach in case it helps someone else get to a lower complexity solution...
Set some condition and introduce simple help variable.
L = 6, x = 3 , y = 2 introduce d = x - y = 1
Condition: if the list of the next number hypotetical value and the previous x - 1 elements values has a number of 0-digits > d next number concrete value must be 1, otherwise add two brances with both 1 and 0 as concrete value.
Start: check(Condition) => both 0,1 due to number of total zeros in the 0-count check.
Empty => add 0 and 1
Step 1:Check(Condition)
0 (number of next value if 0 and previous x - 1 zeros > d(=1)) -> add 1 to sequence
1 -> add both 0,1 in two different branches
Step 2: check(Condition)
01 -> add 1
10 -> add 1
11 -> add 0,1 in two different branches
Step 3:
011 -> add 0,1 in two branches
101 -> add 1 (the next value if 0 and prev x-1 seq would be 010, so we prune and set only 1)
110 -> add 1
111 -> add 0,1
Step 4:
0110 -> obviously 1
0111 -> both 0,1
1011 -> both 0,1
1101 -> 1
1110 -> 1
1111 -> 0,1
Step 5:
01101 -> 1
01110 -> 1
01111 -> 0,1
10110 -> 1
10111 -> 0,1
11011 -> 0,1
11101 -> 1
11110 -> 1
11111 -> 0,1
Step 6 (Finish):
011011
011101
011110
011111
101101
101110
101111
110110
110111
111011
111101
111110
111111
Now count. I've tested for L = 6, x = 4 and y = 2 too, but consider to check the algorithm for special cases and extended cases.
Note: I'm pretty sure some algorithm with Disposition Theory bases should be a really massive improvement of my algorithm.
So in a series of Len binary digits, you are looking for a x-long segment that contains y 1's ..
See the execution: http://ideone.com/xuaWaK
Here's my Algorithm in Java:
import java.util.*;
import java.lang.*;
class Main
{
public static ArrayList<String> solve (String input, int x, int y)
{
int s = 0;
ArrayList<String> matches = new ArrayList<String>();
String segment = null;
for (int i=0; i<(input.length()-x); i++)
{
s = 0;
segment = input.substring(i,(i+x));
System.out.print(" i: "+i+" ");
for (char c : segment.toCharArray())
{
System.out.print("*");
if (c == '1')
{
s = s + 1;
}
}
if (s == y)
{
matches.add(segment);
}
System.out.println();
}
return matches;
}
public static void main (String [] args)
{
String input = "011010101001101110110110101010111011010101000110010";
int x = 6;
int y = 4;
ArrayList<String> matches = null;
matches = solve (input, x, y);
for (String match : matches)
{
System.out.println(" > "+match);
}
System.out.println(" Number of matches is " + matches.size());
}
}
The number of patterns of length X that contain at least Y 1 bits is countable. For the case x == y we know there is exactly one pattern of the 2^x possible patterns that meets the criteria. For smaller y we need to sum up the number of patterns which have excess 1 bits and the number of patterns that have exactly y bits.
choose(n, k) = n! / k! (n - k)!
numPatterns(x, y) {
total = 0
for (int j = x; j >= y; j--)
total += choose(x, j)
return total
}
For example :
X = 4, Y = 4 : 1 pattern
X = 4, Y = 3 : 1 + 4 = 5 patterns
X = 4, Y = 2 : 1 + 4 + 6 = 11 patterns
X = 4, Y = 1 : 1 + 4 + 6 + 4 = 15 patterns
X = 4, Y = 0 : 1 + 4 + 6 + 4 + 1 = 16
(all possible patterns have at least 0 1 bits)
So let M be the number of X length patterns that meet the Y criteria. Now, that X length pattern is a subset of N bits. There are (N - x + 1) "window" positions for the sub pattern, and 2^N total patterns possible. If we start with any of our M patterns, we know that appending a 1 to the right and shifting to the next window will result in one of our known M patterns. The question is, how many of the M patterns can we add a 0 to, shift right, and still have a valid pattern in M?
Since we are adding a zero, we have to be either shifting away from a zero, or we have to already be in an M where we have an excess of 1 bits. To flip that around, we can ask how many of the M patterns have exactly Y bits and start with a 1. Which is the same as "how many patterns of length X-1 have Y-1 bits", which we know how to answer:
shiftablePatternCount = M - choose(X-1, Y-1)
So starting with M possibilities, we are going to increase by shiftablePatternCount when we slide to the right. All patterns in the new window are in the set of M, with some patterns now duplicated. We are going to shift a number of times to fill up N by (N - X), each time increasing the count by shiftablePatternCount, so the full answer should be :
totalCountOfMatchingPatterns = M + (N - X)*shiftablePatternCount
edit - realized a mistake. I need to count the duplicates of the shiftable patterns that are generated. I think that's doable. (draft still)
I am not sure about my answer but here is my view.just take a look at it,
Len=4,
x=3,
y=2.
i just took out two patterns,cause pattern must contain at least y's 1.
X 1 1 X
1 X 1 X
X - represent don't care
now count for 1st expression is 2 1 1 2 =4
and for 2nd expression 1 2 1 2 =4
but 2 pattern is common between both so minus 2..so there will be total 6 pair which satisfy the condition.
I happen to be using a algoritem similar to your problem, trying to find a way to improve it, I found your question. So I will share
static int GetCount(int length, int oneBits){
int result = 0;
double count = Math.Pow(2, length);
for (int i = 1; i <= count - 1; i++)
{
string str = Convert.ToString(i, 2).PadLeft(length, '0');
if (str.ToCharArray().Count(c => c == '1') == oneBits)
{
result++;
}
}
return result;
}
not very efficent I think, but elegent solution.

What does this loop do?

What does the following loop do?
k = 0
while(b!=0):
a = a^b
b = (a & b) << 1
k = k + 1
where a, b and k integers.
Initially a = 2779 and b = 262 then what will be the value of k after the termination of the loop?
I'd be happy if you people try solving the problem manually rather than programmatically.
EDIT : Dropping the tags c and c++. How can I solve the problem manually?
After this chunk is executed:
a = a^b ;
b = (a & b) << 1;
b will take on the integer representation of whatever bits were both set in b and not set in a. Assuming that the input numbers will be of the form 2x, a will become a + b, and b will be itself multiplied by 2 (due to shifting). This means that the loop will terminate when the MSB of a and b are the same (which will be 780th bit in this example). Since b starts off at the 63th bit, there will eventually be 718 iterations: 780 - 63 + 1 (the last iteration) = 718.
You can see this when you step through this with a = 21 and b = 20:
a = 10
b = 01
k = 0
a = 11
b = 10
k = 1
a = 01 (a + b no longer holds here, but it is irrelevant as this is the termination case)
b = 00
k = 2
What does the following loop do?
It computes [power of a] - [power of b] + 1
If you look at the bit-patterns it becomes quite clear. For initial values of a = 210 and b = 25 it looks like this:
k = 0, a = 10000000000, b = 100000
k = 1, a = 10000100000, b = 1000000
k = 2, a = 10001100000, b = 10000000
k = 3, a = 10011100000, b = 100000000
k = 4, a = 10111100000, b = 1000000000
k = 5, a = 11111100000, b = 10000000000
Here is an ideone.com demo.
For the values you mention in your post I get k = 718.
In a language that supports numbers this big, the answer is 718, and the question is not at all interesting either way.
It looks like the loop is performing a series of bitwise operations while incrementing k by 1 at each iteration.
There's a decent-looking tutorial about bitwise operators here.
Hope that helps.
Since you have mentioned that a qnd b is an integer, i think the value 2779 is too big for a integer variable to accommodate this is same for the variable b 262 as well. So both will have there minimum value I think , so after executing a = a^b ;
b = (a & b) << 1; these statements the value of a and be will be 0. and k's value will be equal to 1. Since b is 0 , the while loop's condition will be false and it will exit the loop.
EDIT : The answer is applicable for a programming language like C/C++ or C#
It's not really C syntax.. If we consider that the code is sequential, I am agree with #Paul. But, considering that
a + b == (a^b) + ((a&b) << 1)
where a^b is the sum without applying carry from each bit, and (a&b)<<1 is carry from each bit, we could say that it performs a sum, IFF C code would be
int k = 0;
while(b){
int old_a = a;
a = a^b;
b = (old_a & b) << 1; // note that the need the original value of a here
k++; // number of recursion levels for carry
};
The difference in code could be because of "paralel" way of execution in the original code (or language).

Resources