I am reading four files byte by bytes and comparing all four of those bytes to make one final byte from those four bytes. The way it works is:
- If all bytes are
0, then output0 - If all but 1 byte are
0, then output the odd-byte-out (If the bytes were0, 0, 1, 0, then I would output a1) - If 2 bytes are
0, then I randomly output one of the non-0bytes - If 1 byte is
0, then I output the most occurring byte from the other 3, or otherwise in case of a tie I output a random byte from that set - If all bytes are non-
0, then I output the most occurring byte, or otherwise in case of a tie I output a random byte from that set
One important thing to note is that “random” does not literally have to be random, I can choose the most convenient one.
So I have given this some thought, but I still cannot come up with the absolute fastest way of getting an output from these numbers. One thing I noticed those is if the first two bytes I read are the same and non-zero, then I can skip the next two bytes and just output one of the first two bytes. If the first three bytes are 0, then I can output the last byte. I can also check the third byte with the first byte and second byte to see if they are equal so I can avoid going onto the 4th byte, but I need this to be literally as efficient as possible. I need to run over this algorithm about 8 billion times, and so every little bit counts =)
So anyways, what is the most efficient way to go about doing this? (pseudocode? or otherwise)
This is what the program looks like (the shell of it at least):
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class reconstructerv2 {
public static void main(String[] args) throws IOException {
FileInputStream in1 = null;
FileInputStream in2 = null;
FileInputStream in3 = null;
FileInputStream in4 = null;
FileOutputStream out = null;
try {
in1 = new FileInputStream("1.dd");
in2 = new FileInputStream("2.dd");
in3 = new FileInputStream("3.dd");
in4 = new FileInputStream("4.dd");
BufferedInputStream in1b = new BufferedInputStream(in1);
BufferedInputStream in2b = new BufferedInputStream(in2);
BufferedInputStream in3b = new BufferedInputStream(in3);
BufferedInputStream in4b = new BufferedInputStream(in4);
out = new FileOutputStream("final.dd");
int a;
int b;
int c;
int d;
int o;
while ((a = in1.read()) != -1) {
b = in2.read();
if (a == b && a != 0)
o = a;
else {
c = in3.read();
d = in4.read();
}
System.out.println((byte) c);
out.write((byte) o);
}
} finally {
if (in1 != null) {
in1.close();
in2.close();
in3.close();
in4.close();
}
if (out != null) {
out.close();
}
}
}
}
EDIT: 8 billion, not 8 million
EDIT2: As pointed out in the comments, I can’t skip reading over characters due to synchronization.
Output a+b+c+d.
Same as above. This already saves you a case. If any three bytes are zero, output the sum.
These cases are really all the same. Output the most-occurring of the non-zero bytes, or a random one in the event of a tie.
So there are really only two cases to consider: at least three zero bytes, and two or fewer.
As a matter of fact all the cases are the same. You can apply the second solution above to all the cases. It may well be quicker not to separate them at all.
But first added BufferedInputStreams around those FileInputStreams.