building combination table out of classic order [closed] - java

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I would like to built a combination table for example 4 number of 5 samples(0 -4), but not in the right order. The table should start with the combinations of 0 and 1; than 0,1 2; than 0,1,2,3; than 0,1,2,3,4. Of course the table should not have repetition. I need an algorithm to do it but I can not find any until now. After that I have to write a java code. At the end the table should look like this:
0 0 0 1
0 0 1 0
0 1 0 0
1 0 0 0
0 0 1 1
0 1 0 1
0 1 1 0
1 0 1 0
1 1 0 0
0 1 1 1
.... ... ... ...
1 1 1 1
0 0 0 2
.... ... ... ...
2 0 0 0
... ... ... ...
0 0 1 2
.... ... ... ...
2 2 2 2
0 0 0 3
.... ... ... ...
3 0 0 0
0 0 1 3
.... ... ... ...
3 2 2 2
... ... ... ...
3 3 3 3
.... .... ...... ...
4 4 4 4

You could start with 0000 and increment by 1 (in base 2,3,4,5) until you overflow. E.g.
Base 2:
0000 + 1 => 0001
0001 + 1 => 0010
0010 + 1 => 0011
...
1110 + 1 => 1111
Base 3:
0000 + 1 => 0001
0001 + 1 => 0002
0002 + 1 => 0010
...
2221 + 1 => 2222
And similar for bases 4 and 5.
If you care about repeats (e.g. 0001 is repeated in base 2 and 3) then you can just increment until: for base 2 you have at least a single 1, for base 3 you have at least a single 2, etc...
Java Example:
public static void main(String... args){
int n = 4;
// for base 1, 2, 3, 4, 5 (base 1 gives 0000)
for(int base = 1; base < n + 2; base++)
// for every combination: base^n
for(int j = 0; j < Math.pow(base, n); j++)
// if num contains a (base-1) digit, it's not a dup
if(Integer.toString(j, base).contains(Integer.toString(base-1)))
System.out.println(String.format("%04d",
Integer.parseInt(Integer.toString(j, base))));
}

Related

Complexity of a loop where j shrinks as j = (j - 1) & i

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.

Crossover two individuals of different lengths

I have two individuals I need to perform crossover on that are of different lengths.
The individuals may be like this, but could be much longer:
0 1 2 2 1 2 0 [0] 1 2 1 2 0 1 2 [0] 1 2 1 2 0 2 1 [1]
1 2 1 1 0 2 0 [0] 1 2 1 2 0 0 1 [1]
However, I need to keep their original length after crossover. I also need to ensure that every 8th bit (in square brackets) cannot be a 2. The length of each individual will always be multiples of 8.
How can I perform crossover on these individuals without changing the length and structure of either individual?
I haven't been able to find a solution to this so any help would be greatly appreciated.
I assume you're talking about a single-point crossover. You could do something like this:
Select a random number between 1 and the length of the shorter individual. This will be your crossover point.
Cut both individuals at this point.
Swap them, as per regular crossover.
Example:
0 1 2 2 1 2 0 [0] 1 2 1 2 0 1 2 [0] 1 2 1 2 0 2 1 [1]
1 2 1 1 0 2 0 [0] 1 2 1 2 0 0 1 [1]
The shorter individual has length 16, so we generate a random number between 1 and 16 --> e.g., 9
Crossover point:
|
0 1 2 2 1 2 0 [0] 1|2 1 2 0 1 2 [0] 1 2 1 2 0 2 1 [1]
1 2 1 1 0 2 0 [0] 1|2 1 2 0 0 1 [1]
|
Swap sub-sections after the point:
|
0 1 2 2 1 2 0 [0] 1|2 1 2 0 0 1 [1]
1 2 1 1 0 2 0 [0] 1|2 1 2 0 1 2 [0] 1 2 1 2 0 2 1 [1]
|
This preserves the length of both individuals, and preserves the no-2s-in-brackets rule.
I've tried this type of solution:
it works (but different cross-over location:
the code is in python
from random import choices, randint, randrange, random
a = [1,2,4,5,8,11,3,4,7,2,4,6]
b = [3,4,5,6,9,1,3,6,7]
length_a =len(a)
length_b = len(b)
crossover_prob = 0.8
p = randint(1, length_a - 1)
q = randint(1, length_b -1)
while p < crossover_prob:
c = a[0:p] + b[q:]
while q < crossover_prob:
d = b[0:q] + a[p:]
print (c)
print (d)
result:
[1, 3, 4, 5, 6, 9, 1, 3, 6, 7]
[2, 4, 5, 8, 11, 3, 4, 7, 2, 4, 6]

Java - Bit manipulation (count number of 1s in number)

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>

How do I calculate negation(~) of -5

public class UnaryOperator {
public static void main(String[] args) {
byte a= -5;
System.out.println(~a); // prints 4
}
}
When I do it manually, I get the answer as 6.
Here is how I did it:
128 64 32 16 8 4 2 1
0 0 0 0 0 1 0 1
As it is a negation I inverted it to the following:
128 64 32 16 8 4 2 1
0 0 0 0 0 1 0 1
sign -1 1 1 1 1 0 1 0
-----------------------------
0 0 0 0 1 0 1
add one--> 0 0 0 0 0 1 1
------------------------------
0 0 0 0 1 1 0 = 6
------------------------------
I know there's something wrong with what I am doing but I am not able to figure it out.
5 is 00000101
-5 is 11111010+00000001 = 11111011
~(-5) is 00000100
so you get 4.
You're starting out with -5, which is in two's complement. Thus:
-128 64 32 16 8 4 2 1
1 1 1 1 1 0 1 1 (= -5)
flip: 0 0 0 0 0 1 0 0 (= +4)
I haven't done much bitwise stuff, but after reading wikipedia for a few seconds it seems like NOT -5 = 4, on wikipedia they used NOT x = -x - 1. So the program is correct.
Edit: For unsigned integers, you use NOT x = y - x were y is the maximum number that integer can hold.

Dynamic programming: Find largest diamond (rhombus)

I have a small program to do in Java. I have a 2D array filled with 0 and 1, and I must find the largest rhombus (as in square rotated by 45 degrees) and their numbers.
Example:
0 1 0 0 0 1
1 0 1 1 1 0
1 0 1 1 1 1
0 1 1 1 1 1
0 0 1 1 1 1
1 1 1 1 1 1
Result:
1
1 1 1
1 1 1 1 1
1 1 1
1
The problem is similar to this SO question.
If you have any idea, post it here.
This too long for a comment. I'll post my solution later on if you can't solve it but here's how I've done it (in less than 15 lines of code): I first created a second array (a little big bigger [n+2][n+2]) and did n/2 pass:
0 0 0 0 0 0 0 0
0 0 1 0 0 0 1 0
0 1 0 1 1 1 0 0
0 1 0 1 2 2 1 0
0 0 1 2 2 2 1 0
0 0 0 1 2 2 1 0
0 1 1 1 1 1 1 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 1 0 0 0 1 0
0 1 0 1 1 1 0 0
0 1 0 1 2 2 1 0
0 0 1 2 3 2 1 0
0 0 0 1 2 2 1 0
0 1 1 1 1 1 1 0
0 0 0 0 0 0 0 0
Where a non-zero number x means "I'm the center of a rhombus of size x" (I'm expressing the size in relation with the length of the diagonals [which are both equal in your case] of the rhombus). You can find if you have the center of a rhombus of size (k+1) by checking if {top,right,down,left} are all the centers of rhombus of size k.
The advantage of first creating a bigger array is that it really simplifies your logic but I could do it in place, with a more convoluted logic, by modifying the original array or by using a second array of the same size as the input (once again, it's way easier to simply put a safe "fence" of all-zeroes around your input).
If you don't "surround" your array with a fence, you have a lot of additional if/else checks: this would be prone to errors, lead to bigger code and lead to uglier code.
Short tutorial:
How would you solve the problem if it was a 1x1-field?
How could you formulate the problem recursively?
How could you remember intermediate results and use them?
Do it.
void rhombus()
{
maxr=0;
for (int i=n-1;i>=0;i--)
{
for (int j=n-1;j>=0;j--)
{
if (b[i][j]>0)
{
if ((i==n-1) || (j==n-1) || (i==0) || (j==0)) b[i][j]=1;
else {
b[i][j]=min4(b[i][j+1],b[i][j-1],b[i+1][j],b[i-1][j])+1;
if (b[i][j]==maxr) nrr++;
else if (b[i][j]>maxr) {
nrr=1;
maxr=b[i][j];
}
}
}
}
}
}
Did it,it works,this is my function,where maxr is the max size of the rhombus,and nrr is the number of max sized rhombus.Not sure how it works on huge arrays.(i loop this function n/2 times)

Categories

Resources