String message = "1";
byte[] bytes = message.getBytes();
System.out.println(bytes[0] + ": ");
for (int i = 0; i < 8; i++) {
System.out.print((bytes[0] >> (7 - i)) + " ");
}
Output: 49:
0 0 1 3 6 12 24 49
So my string is 1 which in ASCII is 49. What I'm trying to understand is why do my bits have values 3,6,12,24 and 49? What's happening behind, why aren't they only 0 and 1 like the first 3?
49 in binary is
110001
You shift this same value by 7, 6, 5, 4, ..., (7 - i) bits.
So
00110001 >> 7 ==> 00000000 == 0
00110001 >> 6 ==> 00000000 == 0
00110001 >> 5 ==> 00000001 == 1
00110001 >> 4 ==> 00000011 == 3
...
You can use Integer.toBinaryString(int) to get the binary representation of an integer value as a String.
Because your bit extraction is incorrect. The bit representation for the character '1' is that of 49: 00110001.
You are shifting 7 times, then 6, then 5, etc., but you are not isolating the bits properly.
00110001 >> 7 is 00000000 or 0
00110001 >> 6 is 00000000 or 0
00110001 >> 5 is 00000001 or 1
00110001 >> 4 is 00000011 or 3
00110001 >> 3 is 00000110 or 6
00110001 >> 2 is 00001100 or 12
00110001 >> 1 is 00011000 or 24
00110001 >> 0 is 00110001 or 49
You must do a bitwise-and with 1 to isolate the bit you've shifted to get the 1s and 0s out.
System.out.print( ((bytes[0] >> (7 - i)) & 1) + " ");
Output:
49:
0 0 1 1 0 0 0 1
The last 8 bits of number 49 in binary looks like this:
00110001
When you shift the number right by k bits, it's the same as dividing it in int by 2k. That is what you get in the output (digits to the right of | are dropped):
0 | 0110001 -- 0
00 | 110001 -- 0
001 | 10001 -- 1
0011 | 0001 -- 3
00110 | 001 -- 6
001100 | 01 -- 12
0011000 | 1 -- 24
00110001 | -- 49
When shifting, you shift the bits n positions (in this case to the right).
So:
Loop# 7-i bits result
0 7 000000000 0
1 6 000000000 0
2 5 000000001 1
3 4 000000011 3
4 3 000000110 6
5 2 000001100 12
6 1 000011000 24
7 0 000110001 49
The reason why the first shifts are 0 and 1 is because al significant bits were already shifted out.
If you want to obtain the last bit, you need to perform (a>>s)&1 with a the number and s the bit from right you want.
In case you want to print the binary representation of a, you can simply use Integer.toBinaryString(a);
Your actual data might be 49 but, it needs to fill 8 bit for byte data types.So, if you count 8 bit starting from 0 to 7 (as per your loop).And you are using >> which will right shift.
49 binary is 0 0 1 1 0 0 0 1
0 0 1 1 0 0 0 1 >> 7-0 = 00000000 = 0
0 0 1 1 0 0 0 1 >> 7-1 = 00000000 = 0
0 0 1 1 0 0 0 1 >> 7-2 = 00000001 = 1
0 0 1 1 0 0 0 1 >> 7-3 = 00000011 = 3
0 0 1 1 0 0 0 1 >> 7-4 = 00000110 = 6
0 0 1 1 0 0 0 1 >> 7-5 = 00001100 = 12
0 0 1 1 0 0 0 1 >> 7-6 = 00011000 = 32
0 0 1 1 0 0 0 1 >> 7-7 = 00110001 = 49
Related
The following line of code is inside a for loop where j is incremented and ansString is a string of ASCII characters, like 000\Qg$M!*P000\gQYA+ h000\M|$skd 000\Qo}plsd000\.
ansString[j] = ((char)(paramString[j] >> j % 8 ^ paramString[j]));
I am having trouble with figuring out how to have XOR and all the other operators reversed to find paramString. Appreciate any help.
The right bitshift (>>) and modulo (%) are irreversible operations:
In the case of the right bitshift, underflowed bits are lost, so reversing a >> b would leave you with 2^b different possible results.
For the modulo operator, in x % 8 = y there are 32 possible values for x asuming it has a maximum length of 8 bits. (That would be every x * 8 + y that fit in 8 bits)
The xor operation is the only one reversible. If you have
a ^ b = c
then
c ^ b = a
So for more than one input you would have the same output. For example, lets take the case where j = 0
j % 8 = 0 % 8 = 0
paramString[j] >> (j % 8) = paramString[0] >> 0 = paramString[0]
paramString[0] ^ paramString[j] = paramString[0] ^ paramString[0] = 0
This means that for your first character and every 8th subsequent character (this is every character where its index j is a multiple of 8, so j % 8 = 0) the result will be 0, whichever the original character was (as you can see in your example output string).
This is why, even if you brute-force every possible input (a total of 256 * n possible input strings, being n the string length), you can never be sure of what was the original input, as many inputs yield the same output.
If j is a running index, you will know the shift amount in each iteration. With that, you can find a prefix and decrypt the string.
e.g. for j = 2 (0..7 are bit positions, double digits are XORed bits, x is 0):
Original: 0 1 2 3 4 5 6 7
Shifted: x x 0 1 2 3 4 5
Encrypted: 0 1 02 13 24 35 46 57
As you can see, the first 2 digits remain untouched. And those 2 digits are used to encrypt the next two, and so forth.
So to decrypt with j = 2, you find a 2 digit prefix unencrypted. This can be used to decrypt the next 2 bits (02 and 13):
Encrypted: 0 1 02 13 24 35 46 57
Shift-Mask: x x 0 1 x x x x
Temp1: 0 1 2 3 24 35 46 57
Now we know the first 4 digits, and also the decryption bits for the next 2:
Temp1: 0 1 2 3 24 35 46 57
Shift-Mask: x x x x 2 3 x x
Temp2: 0 1 2 3 4 5 46 57
And again:
Temp2: 0 1 2 3 4 5 46 57
Shift-Mask3: x x x x x x 4 5
Decrypted3: 0 1 2 3 4 5 6 7 <- Original string
Based on this idea, you can build the decryption algorithm
Problem : print all +ve integer solution of the equation
a^3 + b^3 = c^3 + d^3
where a, b, c, d are integers bw 1 to 1000
Facing issue with Math.pow() function.
So I have written two code one is brute force and another one with a little optimisation.
The first one is showing correct output while the 2nd one is not and this is due to the power function.
Math.pow(0,1/3) = 1 while it should be 0
class Find_a3_b3__c3_d3{
// final static int n = 100;
// solution 1 : BRUTE FORCE
public static void bruteForce(){ // O(N^4)
int n = 5;
int resultCount = 0;
for(int a=0; a<n ; a++){
for(int b=0; b<n; b++){
for(int c=0; c<n; c++){
for(int d=0; d<n; d++){
int a_3 = a*a*a;
int b_3 = b*b*b;
int c_3 = c*c*c;
int d_3 = d*d*d;
if(a_3 + b_3 == c_3 + d_3){
System.out.println((resultCount++) + " a: "+a +" b: "+b + " --- c: "+c + " d: "+d );
break;
}
}
}
}
}
System.out.println("\n\n");
}
// solution 2 : BRUTE FORCE
// idea is : as we know d is going to have one value for each pair of a,b & c so
// if we know a b & c , then we can find d by the relation cubeRoot (a_3 + b_3 - c_3);
public static void littleBetter(){ // O(N^4)
int n = 5;
int resultCount = 0;
for(int a=0; a<n ; a++){
for(int b=0; b<n; b++){
for(int c=0; c<n; c++){
int a_3 = a*a*a;
int b_3 = b*b*b;
int c_3 = c*c*c;
System.out.println(a +" " + b+" " + c +" ");
System.out.println(a_3 +" " + b_3+" " + c_3 +" " + Math.pow(a_3 + b_3 - c_3, 1/3));
int d = (int) Math.pow(a_3 + b_3 - c_3, 1/3);
int d_3 = d*d*d;
if(a_3 + b_3 == c_3 + d_3){
System.out.println((resultCount++) + " a: "+a +" b: "+b + " --- c: "+c + " d: "+d );
}
}
}
}
System.out.println("\n\n");
}
public static void main(String[] args) {
bruteForce();// O(n^4)
littleBetter(); // O(n^3)
System.out.println( Math.pow(0,1/3));
System.out.println( Math.pow(0,1));
System.out.println( Math.pow(0,0));
System.out.println( Math.pow(34,0));
System.out.println( Math.pow(34,-0));
System.out.println( Math.pow(0,1));
}
}
If you execute the program, you will see that the no of row of result are different too.
Output
🛑 ~/Documents/CTCI Codes >> javac Find_a3_b3__c3_d3.java
🛑 ~/Documents/CTCI Codes >> java Find_a3_b3__c3_d3
0 a: 0 b: 0 --- c: 0 d: 0
1 a: 0 b: 1 --- c: 0 d: 1
2 a: 0 b: 1 --- c: 1 d: 0
3 a: 0 b: 2 --- c: 0 d: 2
4 a: 0 b: 2 --- c: 2 d: 0
5 a: 0 b: 3 --- c: 0 d: 3
6 a: 0 b: 3 --- c: 3 d: 0
7 a: 0 b: 4 --- c: 0 d: 4
8 a: 0 b: 4 --- c: 4 d: 0
9 a: 1 b: 0 --- c: 0 d: 1
10 a: 1 b: 0 --- c: 1 d: 0
11 a: 1 b: 1 --- c: 1 d: 1
12 a: 1 b: 2 --- c: 1 d: 2
13 a: 1 b: 2 --- c: 2 d: 1
14 a: 1 b: 3 --- c: 1 d: 3
15 a: 1 b: 3 --- c: 3 d: 1
16 a: 1 b: 4 --- c: 1 d: 4
17 a: 1 b: 4 --- c: 4 d: 1
18 a: 2 b: 0 --- c: 0 d: 2
19 a: 2 b: 0 --- c: 2 d: 0
20 a: 2 b: 1 --- c: 1 d: 2
21 a: 2 b: 1 --- c: 2 d: 1
22 a: 2 b: 2 --- c: 2 d: 2
23 a: 2 b: 3 --- c: 2 d: 3
24 a: 2 b: 3 --- c: 3 d: 2
25 a: 2 b: 4 --- c: 2 d: 4
26 a: 2 b: 4 --- c: 4 d: 2
27 a: 3 b: 0 --- c: 0 d: 3
28 a: 3 b: 0 --- c: 3 d: 0
29 a: 3 b: 1 --- c: 1 d: 3
30 a: 3 b: 1 --- c: 3 d: 1
31 a: 3 b: 2 --- c: 2 d: 3
32 a: 3 b: 2 --- c: 3 d: 2
33 a: 3 b: 3 --- c: 3 d: 3
34 a: 3 b: 4 --- c: 3 d: 4
35 a: 3 b: 4 --- c: 4 d: 3
36 a: 4 b: 0 --- c: 0 d: 4
37 a: 4 b: 0 --- c: 4 d: 0
38 a: 4 b: 1 --- c: 1 d: 4
39 a: 4 b: 1 --- c: 4 d: 1
40 a: 4 b: 2 --- c: 2 d: 4
41 a: 4 b: 2 --- c: 4 d: 2
42 a: 4 b: 3 --- c: 3 d: 4
43 a: 4 b: 3 --- c: 4 d: 3
44 a: 4 b: 4 --- c: 4 d: 4
0 0 0
0 0 0 1.0
0 0 1
0 0 1 1.0
0 0 2
0 0 8 1.0
0 0 3
0 0 27 1.0
0 0 4
0 0 64 1.0
0 1 0
0 1 0 1.0
0 a: 0 b: 1 --- c: 0 d: 1
0 1 1
0 1 1 1.0
0 1 2
0 1 8 1.0
0 1 3
0 1 27 1.0
0 1 4
0 1 64 1.0
0 2 0
0 8 0 1.0
0 2 1
0 8 1 1.0
0 2 2
0 8 8 1.0
0 2 3
0 8 27 1.0
0 2 4
0 8 64 1.0
0 3 0
0 27 0 1.0
0 3 1
0 27 1 1.0
0 3 2
0 27 8 1.0
0 3 3
0 27 27 1.0
0 3 4
0 27 64 1.0
0 4 0
0 64 0 1.0
0 4 1
0 64 1 1.0
0 4 2
0 64 8 1.0
0 4 3
0 64 27 1.0
0 4 4
0 64 64 1.0
1 0 0
1 0 0 1.0
1 a: 1 b: 0 --- c: 0 d: 1
1 0 1
1 0 1 1.0
1 0 2
1 0 8 1.0
1 0 3
1 0 27 1.0
1 0 4
1 0 64 1.0
1 1 0
1 1 0 1.0
1 1 1
1 1 1 1.0
2 a: 1 b: 1 --- c: 1 d: 1
1 1 2
1 1 8 1.0
1 1 3
1 1 27 1.0
1 1 4
1 1 64 1.0
1 2 0
1 8 0 1.0
1 2 1
1 8 1 1.0
1 2 2
1 8 8 1.0
3 a: 1 b: 2 --- c: 2 d: 1
1 2 3
1 8 27 1.0
1 2 4
1 8 64 1.0
1 3 0
1 27 0 1.0
1 3 1
1 27 1 1.0
1 3 2
1 27 8 1.0
1 3 3
1 27 27 1.0
4 a: 1 b: 3 --- c: 3 d: 1
1 3 4
1 27 64 1.0
1 4 0
1 64 0 1.0
1 4 1
1 64 1 1.0
1 4 2
1 64 8 1.0
1 4 3
1 64 27 1.0
1 4 4
1 64 64 1.0
5 a: 1 b: 4 --- c: 4 d: 1
2 0 0
8 0 0 1.0
2 0 1
8 0 1 1.0
2 0 2
8 0 8 1.0
2 0 3
8 0 27 1.0
2 0 4
8 0 64 1.0
2 1 0
8 1 0 1.0
2 1 1
8 1 1 1.0
2 1 2
8 1 8 1.0
6 a: 2 b: 1 --- c: 2 d: 1
2 1 3
8 1 27 1.0
2 1 4
8 1 64 1.0
2 2 0
8 8 0 1.0
2 2 1
8 8 1 1.0
2 2 2
8 8 8 1.0
2 2 3
8 8 27 1.0
2 2 4
8 8 64 1.0
2 3 0
8 27 0 1.0
2 3 1
8 27 1 1.0
2 3 2
8 27 8 1.0
2 3 3
8 27 27 1.0
2 3 4
8 27 64 1.0
2 4 0
8 64 0 1.0
2 4 1
8 64 1 1.0
2 4 2
8 64 8 1.0
2 4 3
8 64 27 1.0
2 4 4
8 64 64 1.0
3 0 0
27 0 0 1.0
3 0 1
27 0 1 1.0
3 0 2
27 0 8 1.0
3 0 3
27 0 27 1.0
3 0 4
27 0 64 1.0
3 1 0
27 1 0 1.0
3 1 1
27 1 1 1.0
3 1 2
27 1 8 1.0
3 1 3
27 1 27 1.0
7 a: 3 b: 1 --- c: 3 d: 1
3 1 4
27 1 64 1.0
3 2 0
27 8 0 1.0
3 2 1
27 8 1 1.0
3 2 2
27 8 8 1.0
3 2 3
27 8 27 1.0
3 2 4
27 8 64 1.0
3 3 0
27 27 0 1.0
3 3 1
27 27 1 1.0
3 3 2
27 27 8 1.0
3 3 3
27 27 27 1.0
3 3 4
27 27 64 1.0
3 4 0
27 64 0 1.0
3 4 1
27 64 1 1.0
3 4 2
27 64 8 1.0
3 4 3
27 64 27 1.0
3 4 4
27 64 64 1.0
4 0 0
64 0 0 1.0
4 0 1
64 0 1 1.0
4 0 2
64 0 8 1.0
4 0 3
64 0 27 1.0
4 0 4
64 0 64 1.0
4 1 0
64 1 0 1.0
4 1 1
64 1 1 1.0
4 1 2
64 1 8 1.0
4 1 3
64 1 27 1.0
4 1 4
64 1 64 1.0
8 a: 4 b: 1 --- c: 4 d: 1
4 2 0
64 8 0 1.0
4 2 1
64 8 1 1.0
4 2 2
64 8 8 1.0
4 2 3
64 8 27 1.0
4 2 4
64 8 64 1.0
4 3 0
64 27 0 1.0
4 3 1
64 27 1 1.0
4 3 2
64 27 8 1.0
4 3 3
64 27 27 1.0
4 3 4
64 27 64 1.0
4 4 0
64 64 0 1.0
4 4 1
64 64 1 1.0
4 4 2
64 64 8 1.0
4 4 3
64 64 27 1.0
4 4 4
64 64 64 1.0
1.0
0.0
1.0
1.0
1.0
0.0
🛑 ~/Documents/CTCI Codes >>
When you divide two integers the answer becomes an integer too, that's because you get 1 instead of zero. 1/3 is equal to zero and Math.pow(0,0) is equal to 1. instead you can use Math.pow(0,1./3)) to get 0.UPDATE You can check this to see better solution that are already provided.
As I stated in a comment the problem you encounter is probably due to 1/3 being evaluated as 0. Casting 1 or 3 to a floating point number should solve that.
How ever, I would suggest further optimization: calculate x^3 for x = 1 to n and store results in both an array and a hash set. Then for every combination of 3 numbers in the array test if a+b-c is in the hash set (due to symmetry of a+b you can also spare some duplicates by iterating slightly better on b).
Edit: granted, my optimization sacrifices space complexity.
When using the following code to copy annotated pages, iText 7.1.0 duplicates the /Popup annotation, the only difference between the "original" and the duplicate being that one has a /Parent entry and the other doesn't.
Unfortunately, the one without the missing /Parent is registered in the /Annots list of the /Page dictionary. How can I make iText not duplicate the annotations or at least register the one with the /Parent entry? Any explanation for the odd behavior?
import com.itextpdf.kernel.pdf.*;
import java.io.IOException;
public class CopyPdfTest {
public static void main(String[] args) throws IOException {
PdfDocument inputDoc = new PdfDocument(new PdfReader("input.pdf"));
PdfWriter writer = new PdfWriter("output.pdf");
writer.setCompressionLevel(0);
PdfDocument outputDoc = new PdfDocument(writer);
for (int i = 1; i <= inputDoc.getNumberOfPages(); i++) {
inputDoc.copyPagesTo(i, i, outputDoc);
}
inputDoc.close();
outputDoc.close();
}
}
input.pdf
%PDF-1.4
%âãÏÓ
5 0 obj
<<
/M (D:20180107100338+01'00')
/NM (68bd5c7e-3071-4b10-83ad-6bb2e75a8f3d)
/Subtype /Popup
/Type /Annot
/Parent 4 0 R
/Open false
/F 28
/Rect [352.966 707.883 532.966 827.883]
/P 3 0 R
>>
endobj
6 0 obj
<<
/FormType 1
/Subtype /Form
/Type /XObject
/BBox [115.975 693.768 179.508 827.883]
/Length 69
/Matrix [1 0 0 1 -115.975 -693.768]
>>
stream
1.000 0.000 0.000 RG
2 w
0 J
0 j
116.975 694.768 61.534 132.115 re
S
endstream
endobj
4 0 obj
<<
/Subtype /Square
/RD [0 0 0 0]
/RC (<?xml version="1.0"?><body xmlns="http://www.w3.org/1999/xhtml" xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/" xfa:APIVersion="Acrobat:11.0.0" xfa:spec="2.0.2"><p dir="ltr"><span style="text-align:left;font-size:13pt;font-style:normal;font-weight:normal;color:#000000;font-family:Arial">test</span></p></body>)
/T (thw)
/Contents (test)
/Rect [115.975 693.768 179.508 827.883]
/CA 1
/P 3 0 R
/M (D:20180107100342+01'00')
/Type /Annot
/NM (fd33d765-e844-4226-aff8-3ef81361e787)
/F 4
/BS
<<
/W 2
/S /S
>>
/AP
<<
/N 6 0 R
>>
/C [1 0 0]
/Popup 5 0 R
/Subj (Rectangle)
/CreationDate (D:20180107100338+01'00')
>>
endobj
8 0 obj
<<
/OPM 1
/Type /ExtGState
>>
endobj
7 0 obj
<<
/R7 8 0 R
>>
endobj
9 0 obj
<<
/Length 30
>>
stream
q 0.1 0 0 0.1 0 0 cm
/R7 gs
Q
endstream
endobj
3 0 obj
<<
/pdftk_PageNum 1
/Annots [4 0 R 5 0 R]
/Resources
<<
/ProcSet [/PDF]
/ExtGState 7 0 R
>>
/Type /Page
/Parent 1 0 R
/Contents 9 0 R
/MediaBox [0 0 595 842]
>>
endobj
1 0 obj
<<
/Kids [3 0 R]
/Type /Pages
/Count 1
>>
endobj
11 0 obj
<<
/Type /Catalog
/Pages 1 0 R
>>
endobj
12 0 obj
<<
/ModDate (D:20180108114520+01'00')
/CreationDate (D:20180108114520+01'00')
/Creator (pdftk 2.02 - www.pdftk.com)
/Producer (itext-paulo-155 \(itextpdf.sf.net-lowagie.com\))
>>
endobj xref
0 13
0000000000 65535 f
0000001472 00000 n
0000000000 65535 f
0000001293 00000 n
0000000460 00000 n
0000000015 00000 n
0000000220 00000 n
0000001177 00000 n
0000001130 00000 n
0000001210 00000 n
0000000000 65535 f
0000001531 00000 n
0000001583 00000 n
trailer
<<
/Info 12 0 R
/ID [<10172d770e5713ca1f4b5185f0508476><d91bf66464b334d552196d601c1d2f94>]
/Root 11 0 R
/Size 13
>>
startxref
1779
%%EOF
output.pdf
10 0 obj and 11 0 obj are the duplicated Popups.
%PDF-1.7
%âãÏÓ
5 0 obj
<</Length 30>>stream
q 0.1 0 0 0.1 0 0 cm
/R7 gs
Q
endstream
endobj
4 0 obj
<</Annots[8 0 R 11 0 R]/Contents 5 0 R/MediaBox[0 0 595 842]/Parent 2 0 R/Resources<</ExtGState 6 0 R/ProcSet[/PDF]>>/Type/Page/pdftk_PageNum 1>>
endobj
1 0 obj
<</Pages 2 0 R/Type/Catalog>>
endobj
3 0 obj
<</CreationDate(D:20180108123558+01'00')/ModDate(D:20180108123558+01'00')/Producer(iText® 7.1.0 ©2000-2017 iText Group NV \(AGPL-version\))>>
endobj
2 0 obj
<</Count 1/Kids[4 0 R]/Type/Pages>>
endobj
6 0 obj
<</R7 7 0 R>>
endobj
7 0 obj
<</OPM 1/Type/ExtGState>>
endobj
8 0 obj
<</AP<</N 9 0 R>>/BS<</S/S/W 2>>/C[1 0 0]/CA 1/Contents(test)/CreationDate(D:20180107100338+01'00')/F 4/M(D:20180107100342+01'00')/NM(fd33d765-e844-4226-aff8-3ef81361e787)/P 4 0 R/Popup 10 0 R/RC(<?xml version="1.0"?><body xmlns="http://www.w3.org/1999/xhtml" xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/" xfa:APIVersion="Acrobat:11.0.0" xfa:spec="2.0.2"><p dir="ltr"><span style="text-align:left;font-size:13pt;font-style:normal;font-weight:normal;color:#000000;font-family:Arial">test</span></p></body>)/RD[0 0 0 0]/Rect[115.975 693.768 179.508 827.883]/Subj(Rectangle)/Subtype/Square/T(thw)/Type/Annot>>
endobj
9 0 obj
<</BBox[115.975 693.768 179.508 827.883]/FormType 1/Length 69/Matrix[1 0 0 1 -115.975 -693.768]/Subtype/Form/Type/XObject>>stream
1.000 0.000 0.000 RG
2 w
0 J
0 j
116.975 694.768 61.534 132.115 re
S
endstream
endobj
10 0 obj
<</F 28/M(D:20180107100338+01'00')/NM(68bd5c7e-3071-4b10-83ad-6bb2e75a8f3d)/Open false/P 4 0 R/Parent 8 0 R/Rect[352.966 707.883 532.966 827.883]/Subtype/Popup/Type/Annot>>
endobj
11 0 obj
<</F 28/M(D:20180107100338+01'00')/NM(68bd5c7e-3071-4b10-83ad-6bb2e75a8f3d)/Open false/P 4 0 R/Rect[352.966 707.883 532.966 827.883]/Subtype/Popup/Type/Annot>>
endobj
xref
0 12
0000000000 65535 f
0000000253 00000 n
0000000455 00000 n
0000000298 00000 n
0000000092 00000 n
0000000015 00000 n
0000000506 00000 n
0000000535 00000 n
0000000576 00000 n
0000001204 00000 n
0000001429 00000 n
0000001618 00000 n
trailer
<</ID [<cdbc838ce680aa596f6ff6e5a2a101e7><cdbc838ce680aa596f6ff6e5a2a101e7>]/Info 3 0 R/Root 1 0 R/Size 12>>
%iText-7.1.0
startxref
1794
%%EOF
I have a .cnf file which contains numbers as Conjunctive Normal Form.
I need to read and store them in a data structure (matrix or list) to be able to work with them as index. (I need this to solve a 3-SAT problem.)
How can I read and store them in Java?
c This Formular is generated by mcnf
c
c horn? no
c forced? no
c mixed sat? no
c clause length = 3
c
p cnf 20 91
10 -3 16 0
-8 20 -19 0
2 -6 -20 0
-7 9 3 0
3 15 -14 0
4 15 20 0
11 -9 -6 0
3 -17 19 0
11 5 -12 0
10 3 -15 0
2 15 18 0
-15 12 11 0
18 -19 -8 0
13 20 9 0
11 -10 -14 0
4 18 -9 0
-7 -17 5 0
-7 11 -15 0
6 2 20 0
16 -18 -17 0
4 -13 -20 0
11 17 -8 0
13 -11 -9 0
-11 13 19 0
12 -19 14 0
10 -1 -20 0
19 -20 13 0
13 2 11 0
17 19 -18 0
19 -20 -10 0
-18 16 15 0
-18 7 -20 0
1 -14 -17 0
1 -11 -18 0
-18 8 13 0
-8 4 16 0
-10 1 13 0
9 3 -20 0
-13 4 8 0
17 -11 18 0
18 20 2 0
-20 -1 4 0
-19 2 -9 0
-9 -16 -15 0
-2 12 9 0
5 19 6 0
-8 -5 -13 0
-18 20 -6 0
5 -18 12 0
2 5 19 0
-5 -8 -11 0
-20 -17 11 0
-18 -14 -16 0
-3 -18 -7 0
-11 20 17 0
-1 -15 -13 0
9 -5 11 0
-17 -7 -1 0
-6 -1 -16 0
-3 -15 -19 0
17 14 11 0
-17 12 13 0
16 12 -2 0
14 10 -16 0
8 -4 5 0
-5 16 17 0
-18 -1 -15 0
11 -15 -13 0
16 -9 -7 0
-8 -15 2 0
-19 -10 1 0
12 -15 -20 0
13 -10 9 0
17 7 18 0
20 15 -2 0
-6 -7 -1 0
14 11 15 0
18 13 -9 0
-4 -12 -2 0
-13 -5 -9 0
5 13 16 0
20 -14 -15 0
19 -20 18 0
19 -17 13 0
3 19 14 0
6 3 20 0
-8 -20 -2 0
12 -10 -19 0
-2 -5 -8 0
13 -4 -11 0
-5 -10 19 0
%
0
From a birds-view perspective, the CNF reader pseudo code looks like this (in C#):
StreamReader cnf = openReader(fileName);
int noOfVars = 0;
while (!cnf.EndOfStream)
{
line = cnf.ReadLine().Trim();
if (line.Length >= 1)
{
c = line[0];
if ((noOfVars > 0) &&
((c == '-') || ((c >= '0') && (c <= '9'))))
{
Clause cl = new Clause(line);
ListOfClauses.Add(cl);
}
else if (c == 'c')
{
processCStatement(line);
}
else if (c == 'p')
{
processPStatement(line, ref noOfVars, ref noOfClauses);
}
else
{
error("Statement has neither 'c' nor 'p' in first column: " + line[0]);
break;
}
}
}
To construct a Clause object from a CNF line:
public Clause(string line)
{
int id = -1;
string[] arr = line.Split(whitespaceSeparator, StringSplitOptions.RemoveEmptyEntries);
if (arr.Length < 1)
{
raise("Empty clause!");
}
foreach (string s in arr)
{
try
{
id = int.Parse(s);
}
catch (Exception)
{
raise("Invalid literal: " + s);
}
if (id != 0)
{
Literal lit = new Literal(id);
this.Add(lit);
}
}
if (id != 0)
{
raise("Line does not end with '0'");
}
// sort literals and remove duplicates
this.unify();
}
This pseudo code assumes that the CNF ist stored as list of Clause objects. Each Clause is a list of Literal objects. A Literal has a positive variable ID and an inverted or non-inverted polarity.
In terms of performance, it might be better to store the literals as integer arrays (or even bit-sets) rather than as list of objects.
If you want to use the library SAT4J (http://www.sat4j.org/), it will read a .cnf in Java without any problem.
public class Example {
public static void main(String[] args) {
ISolver solver = SolverFactory.newDefault();
Reader reader = new DimacsReader(solver);
// CNF filename is given on the command line
try {
IProblem problem = reader.parseInstance(args[0]);
} catch (FileNotFoundException e) {
} catch (ParseFormatException e) {
} catch (IOException e) {
}
}
}
This library is designed to read and solve CNF formula :). But you can use it just to read as you wanted :).
I am using Matlab, and I have a 1x200 vector of numbers.
I need to assign a "score" to the set of numbers by following these rules:
If there are 2 or 3 or 4 consecutive positive numbers, then 0.5 points
If there are five or more consecutive positive numbers, then 1.0 points
If there isn't any consecutive positive number, for example: 0 0 0 6 0 0, then 0.0 point. (ignore it, consider that positive number as zero)
If there is only one zero in the middle of a run of positive integers, then ignore that zero (consider it as a positive integer)
If there are two or more consecutive zeroes, that breaks the run of consecutive positive numbers.
Example: 30 43 54 0 0 0 41 54 14 10 1 0 0 0 0 32 41 98 12 0 0 0 (2.0 points total)
At the end, there should be a tally of the points.
Are there any useful functions for this type of problem?
This is based on my understanding of the question, as noted in my question above. I've "unsuppressed" all output, so you can see what's going on.
%Rules:
%1. If there are 2 or 3 or 4 consecutive positive numbers, then 0.5 point
%2. If there are five or more consecutive positive numbers, then 1.0 point
%3. And if there isn't any consecutive positive number, for example:
% 0 0 0 6 0 0, then 0.0 point. (ignore it, consider that positive
% number as zero)
%4. if there is only one zero in the middle of positive integers = ignore
% that zero (consider it as a positive integer)
%5. If there are two or more consecutive 0, THEN no point.
%testData = [0 30 43 54 0 0 0 41 54 14 10 1 0 0 0 0 32 41 98 12 0 0 0 1 2 0 1 2 0 ];
testData = [30 43 54 0 0 0 41 54 14 10 1 0 0 0 0 32 41 98 12 0 0 0 ];
posa = testData>0;
%add 0s at each end so that the diffs at the ends work.
diffa = diff([0 posa 0])
starts = find(diffa ==1)
ends = find(diffa==-1)
% Rule 4 if any end (-1) is immediately followed by a start, that means that there
% is a 0 in the middle of a run. substitute a 1 in the position and recalc.
midZeroLengths = starts(2:end) - ends(1:(end-1));
%pad to account for the fact that we only compared part.
midZeroLengths = [midZeroLengths 0];
if any(midZeroLengths == 1);
testData(ends(midZeroLengths==1)) = 1;
posa = testData>0;
%add 0s at each end so that the diffs at the ends work.
diffa = diff([0 posa 0])
starts = find(diffa ==1)
ends = find(diffa==-1)
end
runs = ends-starts
halfs = (runs > 1) & (runs < 5)
wholes = (runs > 4)
final = sum(halfs)*0.5 + sum(wholes)
How about:
str = repmat('a', 1, numel(testData));
str(testData > 0) = 'b';
m = regexp(str, 'b+(ab+)*', 'match');
n = cellfun(#numel, m);
score = 0.5 * sum(n >= 2 & n <= 4) + 1.0 * sum(n >= 5);
Note that I haven't run this, so there may be errors.