What would (0 + 1) % 10? return? How do you deal with numbers on the left being smaller than numbers on the right? How is this even possible?
The modulo is the remainder of an integer division. Say you have integers a and b.
n = a / b (integer), and
m = a % b = a - ( b * n )
Then
b * n + m = a
Examples:
a b n = a/b b * n m = a%b
0 5 0 0 0
1 5 0 0 1
2 5 0 0 2
3 5 0 0 3
4 5 0 0 4
5 5 1 5 0
6 5 1 5 1
....
10 5 2 10 0
12 5 2 10 2
etc.
Basically, the integer division determines how many times b fully fits inside a. If b < a, that's zero times. The modulo operation then returns what is left. If b < a, that's a.
(0 + 1) % 10 would return 1
What is making you confused about small and large numbers in an expression?
Related
What is the time complexity of this code snippet? Why, mathematically, is that?
for (int i = 0; i < n; i++) {
for (int j = i; j > 0; j = (j - 1) & i) {
System.out.println(j);
}
}
The short version:
The runtime of the code is Θ(nlog2 3), which is approximately Θ(n1.585).
The derivation involves counting the number of 1 bits set in ranges of numbers.
Your connection to Pascal's triangle is not a coincidence!
Here's the route that I used to work this out. There's a really nice pattern that plays out in the bits of the numbers as you're doing the subtractions. For example, suppose that our number i is given by 10101001 in binary. Here's the sequence of values we'll see for j:
10101001
10101000
10100001
10100000
10001001
10001000
10000001
10000000
00101001
00101000
00100001
00100000
00001001
00001000
00000001
00000000
To see the pattern, focus on the columns of the number where there were 1 bits in the original number. Then you get this result:
v v v v
10101001 1111
10101000 1110
10100001 1101
10100000 1100
10001001 1011
10001000 1010
10000001 1001
10000000 1000
00101001 0111
00101000 0110
00100001 0101
00100000 0100
00001001 0011
00001000 0010
00000001 0001
00000000 0000
In other words, the sequence of values j takes on is basically counting down from the binary number 1111 all the way down to zero!
More generally, suppose that the number i has b(i) 1 bits in it. Then we're counting down from a number made of b(i) 1 bits down to 0, which requires 2b(i) steps. Therefore, the amount of work the inner loop does is 2b(i).
That gives us the complexity of the inner loop, but to figure out the total complexity of the loop, we need to figure out how much work is done across all n iterations, not just one of them. So the question then becomes: if you count from 0 up to n, and you sum up 2b(i), what do you get? Or, stated differently, what is
2b(0) + 2b(1) + 2b(2) + ... + 2b(n-1)
equal to?
To make this easier, let's assume that n is a perfect power of two. Say, for example, that n = 2k. This will make this easier because that means that the numbers 0, 1, 2, ..., n-1 all have the same number of bits in them. There's a really nice pattern at play here. Look at the numbers from 0 to 7 in binary and work out what 2b(i) is for each:
000 1
001 2
010 2
011 4
100 2
101 4
110 4
111 8
Now look at the numbers from 0 to 15 in binary:
0000 1
0001 2
0010 2
0011 4
0100 2
0101 4
0110 4
0111 8
----
1000 2
1001 4
1010 4
1011 8
1100 4
1101 8
1110 8
1111 16
In writing out the numbers from 8 to 15, we're basically writing out the numbers from 0 to 7, but with a 1 prefixed. This means each of those numbers has the one plus the number of 1 bits set as the previous versions, so 2b(i) is doubled for each of them. So if we know the sum of these terms from 0 to 2k-1, and we want to know the sum of the terms from 0 to 2k+1 - 1, then we basically take the sum we have, then add two more copies of it.
More formally, let's define S(k) = 2b(0) + 2b(1) + ... + 2b(2k - 1). Then we have
S(0) = 1
S(k + 1) = S(k) + 2S(k) = 3S(k)
This recurrence solves to S(k) = 3k. In other words, the sum 2b(0) + 2b(1) + ... + 2b(2k-1) works out to 3k.
Of course, in general, we won't have n = 2k. However, if we write k = log2 n, then we can get an approximation of the number of iterations at roughly
3log2 k
= klog2 3
≈ k1.584...
So we'd expect the runtime of the code to be Θ(nlog2 3). To see if that's the case, I wrote a program that ran the function and counted the number of times the inner loop executed. I then plotted the number of iterations of the inner loop against the function nlog2 3. Here's what it looks like:
]1
As you can see, this fits pretty well!
So how does connect to Pascal's triangle? It turns out that the numbers 2b(i) has another interpretation: it's the number of odd numbers in the ith row of Pascal's triangle! And that might explain why you're seeing combinations pop out of the math.
Thanks for posting this problem - it's super interesting! Where did you find it?
Here is a Java Code snippet:
int i,j,n,cnt;
int bit=10;
int[] mp = new int[bit+1];
n=(1<<bit);
for(i=0;i<n;i++){
mp[Integer.bitCount(i)]++;
if((i&i+1) ==0){ // check 2^k -1, all bit are set, max value of k bit num
System.out.printf("\nfor %d\n",i);
for(j=0;j<=bit;j++){
System.out.printf("%d ",mp[j]);
}
}
}
Output:
for 0 // 2^0 - 1
1 0 0 0 0 0 0 0 0 0 0
for 1 // 2^1 - 1
1 1 0 0 0 0 0 0 0 0 0
for 3 // 2^2 - 1
1 2 1 0 0 0 0 0 0 0 0
for 7 // 2^3 - 1
1 3 3 1 0 0 0 0 0 0 0
for 15 // 2^4 - 1
1 4 6 4 1 0 0 0 0 0 0
for 31 // 2^5 - 1
1 5 10 10 5 1 0 0 0 0 0
for 63 // 2^6 - 1
1 6 15 20 15 6 1 0 0 0 0
for 127 // 2^7 - 1
1 7 21 35 35 21 7 1 0 0 0
for 255 // 2^8 - 1
1 8 28 56 70 56 28 8 1 0 0
for 511 // 2^9 - 1
1 9 36 84 126 126 84 36 9 1 0
for 1023 // 2^10 - 1
1 10 45 120 210 252 210 120 45 10 1
So it looks like Pascal triangle…
0C0
1C0 1C1
2C0 2C1 2C2
3C0 3C1 3C2 3C3
4C0 4C1 4C2 4C3 4C4
5C0 5C1 5C2 5C3 5C4 5C5
6C0 6C1 6C2 6C3 6C4 6C5 6C6
7C0 7C1 7C2 7C3 7C4 7C5 7C6 7C7
8C0 8C1 8C2 8C3 8C4 8C5 8C6 8C7 8C8
9C0 9C1 9C2 9C3 9C4 9C5 9C6 9C7 9C8 9C9
10C0 10C1 10C2 10C3 10C4 10C5 10C6 10C7 10C8 10C9 10C10
In the question above inner loop executes exactly 2^(number set bit) -1 times.
So if we observe we can ses that If k=number of bit, then N=2^k;
Then Complexity becomes: (kC02^0+kC12^1+kC22^2+kC32^3+ … … … +kCk*2^k) - N
If k=10 then N=2^k=1024 So the complexity becomes as follows:
(10C0*2^0+10C1*2^1+10C2*2^2+10C3*2^3+ … … … +10C10*2^10) - 1024
=(1*1 +10*2 + 45*4+ 120*8+210*16+252*32+210*64+120*128+45*256+10*512+1*1024) - 1024
=59049 - 1024
=58025
Here is another code snippet that helps to verify the number 58025.
int i,j,n,cnt;
n=1024;
cnt=0;
for(i=0;i<n;i++){
for(j=i; j>0; j = (j-1)&i){
cnt++;
}
}
System.out.println(cnt);
The output of the above code is 58025.
Can someone explain to my why this method works, I've worked through what it does, but why does this work. Is there a pattern that binary numbers have? Like for example at i = 3, why does it do res[1] + 1 to get 2. How does res[3 >> 1] + (3&1) help to count the number of ones in the binary number of 3?
What the code should do: It works so don't worry about that. It is supposed to return a list that contains the number of ones in the binary representation of each number until num+1. And num is always >= 0. So for num = 5, you would get [0, 1, 1, 2, 1, 2], where the last index represents the number of 1s in the binary representation of 5, and the first index is number of ones in binary rep of 0.
Code:
public int[] countBits(int num) {
int[] res = new int[num+1];
for (int i = 0; i<num+1; i++){
res[i] = res[i >> 1] + (i & 1);
}
return res;
}
This is the part I can't wrap my head around:
res[i] = res[i >> 1] + (i & 1);
EDIT - This is not homework, so please fully explain your answer. This is to help with interviews.
int[] res = new int[num+1];
for (int i = 0; i<num+1; i++){
res[i] = res[i >> 1] + (i & 1);
}
return res;
rewritten as
int[] res = new int[num+1];
for (int i = 0; i<num+1; i++){
x = res[i >> 1];
y = (i & 1);
res[i] = x + y;
}
return res;
Create an array to fit the answers, +1?
for each, starting at the low end.
res[0] = res[0] + 0&1 = 0 + 0 = 0;
res[1] = res[0] + 1&1 = 0 + 1 = 1;
res[2] = res[1] + 0&1 = 1 + 0 = 0;
res[3] = res[1] + 1&1 = 1 + 1 = 2;
Looking at this pattern, I can see that because of the right shift, and the masking with &, it's splitting the problem into 2, one that's been solved previously due to the iteration order, and a bit check of the last digit.
assuming a 8 bit int, for brevity,
1 = 00000001
2 = 00000010
3 = 00000011
Split the binary into parts.
i i>>1 y&1
1 = 0000000 1
2 = 0000001 0
3 = 0000001 1
So it fetches the results for the number of ones in the first half of the array, then counts the last digit.
Because of the iteration order, and array initialisation values, this is guaranteed to work.
For values < 0 , due to 2's compliment it gets hairy, which is why it only works for values >=0
in 'res[i] = res[i >> 1] + (i & 1);'
one number's result is divide into 2 parts
the last bit is 1 or not,which can be calculate by (i & 1).
the first (n-1) bits,this number is equals to res[i >> 1]'s bitcount.this is a simple recursive call
shift by 1 gives the floor number divided by 2.
AND 1 returns 1 if the last bit of the number is 1
Hope the below table helps to see what is happening :) Just my 2 cents.
<pre>
--------------------------------
<b>
# 8 4 2 1 >>1 &1 Ans
</b>
-------------------------------
0 0 0 0 0 0 0 0
1 0 0 0 1 0 1 1
2 0 0 1 0 1 0 1
3 0 0 1 1 1 1 2
4 0 1 0 0 2 0 1
5 0 1 0 1 2 1 2
6 0 1 1 0 3 0 2
7 0 1 1 1 3 1 3
8 1 0 0 0 4 0 1
9 1 0 0 1 4 1 2
10 1 0 1 0 5 0 2
11 1 0 1 1 5 1 3
12 1 1 0 0 6 0 2
13 1 1 0 1 6 1 3
14 1 1 1 0 7 0 3
15 1 1 1 1 7 1 4
</pre>
Suppose I have a Fibonacci sequence of the number x as follows and I want to detect a sequence in an array. Java method should return the length of sequence
x 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610
1)x mod 2 - 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0
2)x mod 3 - 0 1 1 2 0 2 2 1 0 1 1 2 0 2 2 1
Answer 1) 3 (repetitive sequence 011 and length is 3)
2) 8 (repetitive sequence 01120221 and length is 8)
A very simple approach would be to create a copy of the array, and check position 0 of the first array against position 1 of the second array, and if they match, continue checking until the end. If the whole thing matches, then you have a repeating length of 1.
If not, then you compare position 0 of the first array to position 2 of the second array, and follow the same process as above. If this matches, then you have a repeating length of 2.
And you continue this process until you either find a match, or reach the end of the array and can't offset it any further, in which case there is no repeat.
If you are only intending to use this specifically for modulo values of numbers in the Fibonacci sequence, and not for arbitrary data, then the sequence will repeat as soon as you find the second occurrence of a 0 followed by a 1 in the modulo sequence. This is because mod(a + b, n) = mod(mod(a, n) + mod(b, n), n), so the modulo of a number in the Fibonacci sequence (which is the sum of the two previous values) is determined by the previous 2 modulo results. Therefore, once the original pattern of a 0 followed by a 1 reoccurs, the pattern will repeat.
The Following code works:
private static int detectSequence(int[] array) {
int count = 2;
for (int i = 2; i < array.length; i++) {
if(array[i] == 0 && array[i+1] == 1 && i+1 < array.length){
return count;
}
count++;
}
return count;
}
I was trying to solve this question but the automated judge is returning "time limit exceeded" (TLE).
On the occasion of Valentine Day , Adam and Eve went on to take part in a competition.They cleared all rounds and got into the finals. In the final round, Adam is given a even number N and an integer K and he has to find the greatest odd number M less than N such that the sum of digits in binary representation of M is atmost K.
Input format:
For each test case you are given an even number N and an integer K
Output format:
For each test case, output the integer M if it exists, else print -1
Constraints:
1 ≤ T ≤ 104
2 ≤ N ≤ 109
0 ≤ K ≤ 30
Sample input:
2
10 2
6 1
Sample output:
9
1
This is what I have done so far.
static long play(long n, int k){
if(k==0) return -1;
if(k==1) return 1;
long m=n-1;
while(m>0){
long value=Long.bitCount(m); //built in function to count bits
if(value<=k ){
return m;
}
m=m-2;
}
return -1;
}
public void solve(InputReader in, OutputWriter out) {
long start=System.currentTimeMillis();
int t=in.readInt();
while(t-->0){
long n=in.readLong();
int k=in.readInt();
long result=play(n,k);
out.printLine(result);
}
long end=System.currentTimeMillis();
out.printLine((end-start)/1000d+"ms");
}
}
According to updated question N can be between 2 and 10^9. You're starting with N-1 and looping down by 2, so you get up to about 10^9 / 2 iterations of the loop. Not good.
Starting with M = N - 1 is good. And using bitCount(M) is good, to get started. If the initial bitcount is <= K you're done.
But if it's not, do not loop with step -2.
See the number in your mind as binary, e.g. 110101011. Bit count is 6. Let's say K is 4, that means you have to remove 2 bits. Right-most bit must stay on, and you want largest number, so clear the two second-last 1-bits. Result: 110100001.
Now, you figure out how to write that. And do it without converting to text.
Note: With N <= 10^9, it will fit in an int. No need for long.
You'll have to perform bitwise operations to compute the answer quickly. Let me give you a few hints.
The number 1 is the same in binary and decimal notation: 12 = 110
To make the number 102 = 210, shift 1 to the left by one position. In Java and many other languages, we can write this:
(1 << 1) == 2
To make the binary number 1002 = 410, shift 1 to the left by two positions:
(1 << 2) == 4
To make the binary number 10002 = 810 shift 1 to the left by three positions:
(1 << 3) == 8
You get the idea.
To see if a bit at a certain position is 1 or 0, use &, the bitwise AND operator. For example, we can determine that 510 = 1012 has a 1 at the third most significant bit, a 0 at the second most significant bit, and a 1 at the least significant bit:
5 & (1 << 2) != 0
5 & (1 << 1) == 0
5 & (1 << 0) != 0
To set a bit to 0, use ^, the bitwise XOR operator. For example, we can set the second most significant bit of 710 = 1112 to 0 and thus obtain 510 = 1012:
7 ^ (1 << 1) == 5
As the answer is odd,
let ans = 1, here we use 1 bit so k = k - 1;
Now binary representation of ans is
ans(binary) = 00000000000000000000000000000001
while(k > 0):
make 30th position set
ans(binary) = 01000000000000000000000000000001
if(ans(decimal) < N):
k -= 1
else:
reset 30th position
ans(binary) = 00000000000000000000000000000001
Do the same from 29th to 1st position
The example in the book asks the user to enter any positive number. Then the program will add the individual digits separately and print the total. For example if the user enters the number 7512 the program is designed to add 7 + 5 + 1 + 2 and then print the total.
I've written out the way I understand how the code works. Is this correct? Is my understanding of this loop correct with each step, or am I missing any calculations? What happens during the 4th loop when there is no remainder in 7 % 10?
1st run of loop ... sum = sum + 7512 % 10 which is equal to 2
n = 7512 / 10 which which equals to 751
2nd run of loop ... sum = 2 + 751 % 10 which is equal to 1
n = 751 / 10 which is equal to 75
3rd run of loop ... sum = 3 + 75 % 10 which is equal to 5
n = 75 / 10 which is equal to 7
4th run of loop ... sum = 8 + 7 % 10 <------?
import acm.program.*;
public class DigitSum extends ConsoleProgram{
public void run() {
println("This program will add the integers in the number you enter.");
int n = readInt("Enter a positive integer: ");
int sum = 0;
while (n > 0) {
sum += n % 10;
n /= 10;
}
println("The sum of the digits is" + sum + ".");
}
}
The result of the operation 7 % 10 is 7, the remainder when you divide 7 by 10. The last iteration of the loop is to add 7 to the prior value. The next division step inside the loop (n /= 10;) takes n to 0, which is what ends the loop.
% is not the same as /
The % operator is for the modulus, not division... This means that the result of the operations is not dividing, but obtaining the remainder of the division, like:
7512 % 10 => 2
751 % 10 => 1
75 % 10 => 5
7 % 10 => 7
This kind of logic is fairly frequently used when dealing with numeric operations.
before run, sum = 0, n = 7512
1st run of loop ... sum = 0 + 2 => sum = 2, n = 751
2nd run of loop ... sum = 2 + 1 => sum = 3, n = 75
3rd run of loop ... sum = 3 + 5 => sum = 8, n = 7
4th run of loop ... sum = 8 + 7 => sum = 15, n = 0
After 7%10 you get 7 and that is added to your result.
And 7/10 will result in 0 and hence your loop ends and your sum now has addition that you want.